当前位置: 首页 > 知识库问答 >
问题:

我是.NET Core 2.1MVC的新手,我不太了解一些事情是如何工作的

柴翰藻
2023-03-14

我目前正在学习Udemy的.NET Core Angular 8教程。我可以在Postman中获取/发布请求,我还可以使用sqlite作为数据库查看我在.Db文件中发布的内容,并通过Db浏览器查看数据。看起来一切都很好,但如果我不能理解应用程序的某些领域发生了什么,那就什么都没有了。如果有人能帮我回答几个问题,我将不胜感激。

我的整个项目都在GitHub中:https://github.com/cjtejada/asp.netcoreangular8/tree/master/datingapp.api

问题1:我有以下的以下控制器:

    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {

        private readonly IAuthRepository _repo;
        private readonly IConfiguration _config;

        public AuthController(IAuthRepository repo, IConfiguration config)
        {
            _repo = repo;
            _config = config;
        }

        [HttpPost("register")]
        public async Task<IActionResult> Register(UserForRegisterDto userForRegisterDto)
        {
            // validate request

            userForRegisterDto.Username = userForRegisterDto.Username.ToLower();

            if (await _repo.UserExists(userForRegisterDto.Username))
                return BadRequest("User already exists");

            var userToCreate = new User
            {
                Username = userForRegisterDto.Username
            };

            var createdUser = await _repo.Register(userToCreate, userForRegisterDto.Password);

            return StatusCode(201);
        }
    }
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<DataContext>(x => x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddCors();
        services.AddScoped<IAuthRepository, AuthRepository>(); //<---- This Line
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });
    }

在这两个“链接”之后,就可以通过AuthRepository类访问UserExists()方法:

public class AuthRepository : IAuthRepository
{
    private readonly DataContext _context;
    public AuthRepository(DataContext context)
    {
        _context = context;
    }

    public async Task<User> Login(string username, string password)
    {

    }

    private bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
    {

    }

    public async Task<User> Register(User user, string password)
    {
        byte[] passwordHash, passwordSalt;
        CreatePasswordHash(password, out passwordHash, out passwordSalt);

        user.PasswordHash = passwordHash;
        user.PasswordSalt = passwordSalt;

        await _context.Users.AddAsync(user);
        await _context.SaveChangesAsync();

        return user;
    }

    private void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
    {


    }

    public async Task<bool> UserExists(string username)
    {
        if (await _context.Users.AnyAsync(x => x.Username == username))
            return true;

        return false;
    }
}

我一直在读AddScoped方法和它的功能,但我并不清楚情况是这样的。任何关于如何工作的澄清都是很好的。

问题二:这一个或多或少是一样的。如果我们继续遵循请求的路径,我们将访问AuthRepository类中的register()方法

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<DataContext>(x => x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddCors();
        services.AddScoped<IAuthRepository, AuthRepository>();
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            //app.UseHsts();
        }

        //app.UseHttpsRedirection();
        app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
        app.UseAuthentication();
        app.UseMvc();
    }
}
public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base (options){}
    public DbSet<Value> Values { get; set; }
    public DbSet<User> Users { get; set; }
}

共有1个答案

洪季萌
2023-03-14

>

  • 你是对的。行services.addscoped (); 只是指示ASP.NET核心服务容器在运行时看到对iauthrepository的引用时替换具体类authrepository的实例。

    不同的add*方法在注册interface=>类的映射方面都做了相同的事情,关键的区别是创建的类的范围,即它持续多长时间:

    • AddScoped类将在对服务器的每个请求开始时创建,并在每个请求结束时销毁。换句话说,每个请求都会导致创建该类的一个新实例。
    • AddSingleton类在ASP.NET核心应用程序启动时创建,在其关闭时销毁。换句话说,应用程序中只存在该类的一个实例。
    • 每当请求
    • AddTransient类时,都会重新创建类。换句话说,如果站点上的一个页面两次使用相同的服务瞬变,将会创建两个实例。(与作用域服务相比,作用域服务只创建一个实例,因为每个页面都是一个请求。)


    详细说明,包括示例:https://stackoverflow.com/A/38139500/70345

    为了通过创建authrepository类的实例来实现(1),服务容器需要调用该类的构造函数。容器检查您的类以查找第一个公共构造函数,并检索该构造函数的任何参数,在本例中是DataContext类的实例。然后,容器在其内部类映射中搜索该类,并且由于您已经通过services.addDBContext (...) 注册了该映射,因此能够构造并返回类实例。因此,它能够将该实例传递给authrepository,从而成功地构造了authrepository

    adddbcontext方法只是addscoped的包装器,它执行一些附加的支架,以允许实体框架dbcontext正确工作。

  •  类似资料:
    • 想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。 创建一个简单的 Java 程序,该程序使用一个参数实现方法,该参数将返回变量的平方值。 示例输出:x的值是:10,10的平方值是:100

    • 我遇到了这个问题 据我所知,加密/非加密websocket连接都依赖于代理服务器通过适当的头发送。 来自关于未加密websocket连接的文章 如果未加密的WebSocket流量在流向WebSocket服务器的过程中通过一个透明代理,那么实际上连接很可能会失败,因为浏览器不会 关于加密的web套接字连接 对于透明代理服务器,浏览器不知道代理服务器,因此不发送HTTP CONNECT方法。但是,由于

    • 假设我的接口按如下方式扩展了CrudRepository 我在服务类中使用EmployeeRepository接口,如下所示 错误很明显,因为接口EmployeeRepository不是由任何类实现的,并且 Autowired将失败,因为没有类实现EmployeeRepository。 不过,我对它是如何工作感到困惑的,因为我在GitHub和tutorial上看到的每一个代码都能完美地工作。

    • 为了添加另一个信息,我有一个tasks表,它当然需要引用来跟踪分配给谁,我还有一个列跟踪创建任务的用户。这将分别是和。 虽然有更多的表引用回该键。我可能已经有8个推荐人了。我相信到目前为止我已经把它设计得很好了,但是根据我所提到的,这听起来好吗?

    • 当我尝试编译这段代码时,Eclipse会出现以下两个错误: > 用于函数:maxmin的非法修饰符;只允许最终 对于:Mn不能解析为变量 为什么会出现这两个错误? 我想这可能已经回答了这个问题,但我不明白其中使用的术语。 这是我的代码:

    • 我有一个h:inputText的问题,我不知道如何解决它。 我正在使用JSF和RichFaces开发一个xhtml页面,其中包含日历、SelectOneMenu、InputExtArea和Input等字段。在我的表单末尾,有两个按钮“打印”和“保存”。 如果其中一个字段被修改(文本、日期等),我必须禁用打印按钮。在每个字段中,我都添加了ajax事件。 例如: 如果我的日期改变了,我调用存储在bea