我正在使用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,并且在数据库中不会创建任何内容。我也在我的控制器中加入了一个调试点,但它没有打到它。
我在做什么错?