0

我正在使用ASP.NetCore 1.1和Ef core 1.1以MySql作为我的数据库构建Web API。我正在关注(https://fullstackmark.com/post/10/user-authentication-with-angular-and-asp-net-core)教程来实现用户注册。ASP.NET核心Web API用户注册失败

我已经创建了两个模型:

public class ApplicationUser : IdentityUser 
{ 
    // Extended Properties 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 
public class Stakeholder 
{ 
    public int Id { get; set; } 
    public string IdentityId { get; set; } 
    public ApplicationUser Identity { get; set; } // navigation property 

} 

我还有RegistrationViewModel:

[Validator(typeof(RegistrationViewModelValidator))] 
public class RegistrationViewModel 
{ 
    public string Email { get; set; } 
    public string Password { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

而且它的验证:

public class RegistrationViewModelValidator : AbstractValidator<RegistrationViewModel> 
{ 
    public RegistrationViewModelValidator() 
    { 
     RuleFor(vm => vm.Email).NotEmpty().WithMessage("Email cannot be empty"); 
     RuleFor(vm => vm.Password).NotEmpty().WithMessage("Password cannot be empty"); 
     RuleFor(vm => vm.FirstName).NotEmpty().WithMessage("FirstName cannot be empty"); 
     RuleFor(vm => vm.LastName).NotEmpty().WithMessage("LastName cannot be empty"); 
    } 
} 

我的DbContext:

public class WebAPIDataContext : IdentityDbContext<ApplicationUser> 
{ 
    public WebAPIDataContext(DbContextOptions<WebAPIDataContext> options) 
     : base(options) 
    { 
    } 

    public DbSet<Profile> Profiles { get; set; } 
    public DbSet<User_Task> User_Tasks { get; set; } 
    public DbSet<Feature> Features { get; set; } 
    public DbSet<Stakeholder> Stakeholders { get; set; } 


} 

此外我还写了一个映射类如图教程:

public class ViewModelToEntityMappingProfile : AutoMapper.Profile 
    { 
     public ViewModelToEntityMappingProfile() 
     { 
       CreateMap<RegistrationViewModel,ApplicationUser>().ForMember(au => au.UserName, map => map.MapFrom(vm => vm.Email)); 
     } 
    } 

我的完整startup.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using Microsoft.AspNetCore.Builder; 
using Microsoft.AspNetCore.Hosting; 
using Microsoft.Extensions.Configuration; 
using Microsoft.Extensions.DependencyInjection; 
using Microsoft.Extensions.Logging; 
using Vision_backlog_backend.Models; 
using Vision_backlog_backend.Repository; 
using Microsoft.EntityFrameworkCore; 
using Swashbuckle.AspNetCore.Swagger; 
using Microsoft.IdentityModel.Tokens; 
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 

namespace Vision_backlog_backend 
{ 
    public class Startup 
    { 

     public Startup(IHostingEnvironment env) 
     { 
      var builder = new ConfigurationBuilder() 
       .SetBasePath(env.ContentRootPath) 
       .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) 
       .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
       .AddEnvironmentVariables(); 
      Configuration = builder.Build(); 
     } 

     public IConfigurationRoot Configuration { get; } 

     // This method gets called by the runtime. Use this method to add services to the container. 
     public void ConfigureServices(IServiceCollection services) 
     { 
      // Add framework services. 
      services.AddDbContext<WebAPIDataContext>(options => 
      { 
       options.UseMySql(Configuration.GetConnectionString("MysqlConnection"), 
        b => b.MigrationsAssembly("Vision_backlog_backend")); 
      }); 


      services.AddScoped<IProfileRepository, ProfileRepository>(); 
      services.AddScoped<IUser_TaskRepository, User_TaskRepository>(); 
      services.AddScoped<IFeatureRepository, FeatureRepository>(); 

      services.AddCors(options => 
      { 
       options.AddPolicy("CorsPolicy", 
        builder => builder.AllowAnyOrigin() 
        .AllowAnyMethod() 
        .AllowAnyHeader()); 
      }); 

      services.AddMvc(); 

      services.AddSwaggerGen(c => 
      { 
       c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" }); 
      }); 


     } 

     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
     { 
      loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
      loggerFactory.AddDebug(); 

      // global policy - assign here or on each controller 
      app.UseCors("CorsPolicy"); 


      app.UseMvc(); 

      // Enable middleware to serve generated Swagger as a JSON endpoint. 
      app.UseSwagger(); 

      // Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint. 
      app.UseSwaggerUI(c => 
      { 
       c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); 
      }); 

     } 
    } 
} 

最后我创造AccountsController:

[Route("api/[controller]")] 
public class AccountsController : Controller 
{ 
    private readonly WebAPIDataContext _appDbContext; 
    private readonly UserManager<ApplicationUser> _userManager; 
    private readonly IMapper _mapper; 

    public AccountsController(UserManager<ApplicationUser> userManager, IMapper mapper, WebAPIDataContext appDbContext) 
    { 
     _userManager = userManager; 
     _mapper = mapper; 
     _appDbContext = appDbContext; 
    } 

    // POST api/accounts 
    [HttpPost] 
    public async Task<IActionResult> Post([FromBody]RegistrationViewModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     var userIdentity = _mapper.Map<ApplicationUser>(model); 

     var result = await _userManager.CreateAsync(userIdentity, model.Password); 

     if (!result.Succeeded) return new BadRequestObjectResult(Errors.AddErrorsToModelState(result, ModelState)); 

     await _appDbContext.Stakeholders.AddAsync(new Stakeholder { IdentityId = userIdentity.Id }); 
     await _appDbContext.SaveChangesAsync(); 

     return new OkObjectResult("Account created"); 
    } 
} 

我做了第一次迁移并更新了数据库,创建了表。如果我启动服务器并点击localhost:4784/api/Accounts,我将得到一个状态代码500,并且在数据库中不会创建任何内容。我也在我的控制器中加入了一个调试点,但它没有打到它。

我在做什么错?

回答

0

我必须在startup.cs中添加services.AddAutoMapper();,但它仍然出现编译错误,所以经过几个小时的搜索后,我意识到我必须安装AutoMapper.Extensions.Microsoft.DependencyInjection

之后,上述代码工作,用户注册成功。