c# - 为什么 ComplexTypeModelBinder 无法创建自动生成的 RegisterModel 实例?
问题描述
我正在根据 OWIN 规范 MVC 架构在 asp.net 核心上编写应用程序。使用 Visual Studio 的 UI 配置用户身份。做了一些更改,尝试注册用户,尝试注册用户后出现这样的错误:InvalidOperationException: Could not create an instance of type 'Forum.Areas.Identity.Pages.Account.RegisterModel'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Alternatively, give the 'model' parameter a non-null default value
.
启动.cs
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.AddIdentity<ForumUser, ForumRole>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddControllersWithViews();
services.AddRazorPages();
// other services configuration (MVC, Localization, EmailSending ...)
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
// Localization, endpoints ...
}
}
ForumUser
andForumRole
是空端继承自IdentityUser
and IdentityRole
。我的RegisterModel
:
[AllowAnonymous]
public class RegisterModel : PageModel
{
private readonly SignInManager<ForumUser> _signInManager;
private readonly UserManager<ForumUser> _userManager;
private readonly ILogger<RegisterModel> _logger;
private readonly IEmailSender _emailSender;
public RegisterModel(
UserManager<ForumUser> userManager,
SignInManager<ForumUser> signInManager,
ILogger<RegisterModel> logger,
IEmailSender emailSender)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_emailSender = emailSender;
}
[BindProperty]
public InputModel Input { get; set; }
public string ReturnUrl { get; set; }
public IList<AuthenticationScheme> ExternalLogins { get; set; }
public class InputModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[Display(Name = "Username")]
public string Username { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public async Task OnGetAsync(string returnUrl = null)
{
ReturnUrl = returnUrl;
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
// Sending email confirmation
return Page();
}
}
Register
看法
@page
@model RegisterModel
@{
ViewData["Title"] = "Register";
}
<h1>@ViewData["Title"]</h1>
<div class="row">
<div class="col-md-4">
<form asp-controller="Account" asp-action="Register"asp-route-returnUrl="@Model.ReturnUrl" method="post">
<h4>Create a new account.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Username"></label>
<input asp-for="Input.Username" class="form-control" />
<span asp-validation-for="Input.Username" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.ConfirmPassword"></label>
<input asp-for="Input.ConfirmPassword" class="form-control" />
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
</div>
</div>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
有人可以告诉我为什么 ComplexTypeModelBinder 无法创建自动生成的(以及一些由我修改的)RegisterModel 的实例吗?我试图将 RegisterModel 回滚到其原始状态,但错误仍然存在。
解决方案
解决方案:我只是将方法的签名更改public async Task<IActionResult> Register(RegisterModel model, IEmailSender emailSender)
为public async Task<IActionResult> Register(RegisterModel.InputModel input)
(将参数类型更改RegisterModel
为RegisterModel.InputModel
并移至IEmailSender
构造函数(因为它抛出了相同的异常)。所以问题解决了,但我仍然不知道为什么这个异常(Model bound complex types must not be abstract or value types and must have a parameterless constructor
对于两者RegisterModel
和IEmailSender
)都飞了. 有一个选项可以创建我自己的(自定义)数据绑定器,但我认为这是一个糟糕且有点拐杖的解决方案。
推荐阅读
- android - 无法使用 Firebase 云消息传递在浏览器中打开 URL
- python - 如何使用堆叠在 python 中的相同装饰器?
- excel - 从 Now() 函数单元触发更改事件的问题
- java - 即使 redo() 工作正常,为什么 UndoManager.canRedo() 会返回 false?
- javascript - 如何在javascript中动态添加带有id的列表项?
- ebay-api - findItemsAdvanced 突然失败:与服务器的连接异常终止
- javascript - 如何设置 2 个屏幕截图桌面调用之间的时间延迟?
- python-3.x - 包含值的排序列表:无,结果为 TypeError:“NoneType”和“str”的实例之间不支持“<”
- javascript - 我应该如何处理这个nodejs代码来做正确的事情?
- perl - Perl 问题:grep 后删除的内容