问题
I have the following on my Login.cshtml.cs code file:
Login.cshtml.cs
public class LoginModel : PageModel
{
public string ReturnUrl { get; set; }
public bool EnableLocalLogin { get; set; } = true;
public string Username { get; set; }
public string Password { get; set; }
private readonly IIdentityServerInteractionService _interaction;
public LoginModel(IIdentityServerInteractionService interaction)
{
_interaction = interaction;
}
public IActionResult OnGet(string returnUrl)
{
ReturnUrl = returnUrl;
return Page();
}
public IActionResult OnPost([FromBody]LoginModel model, string button)
{
// todo - implement
return Page();
}
}
If I have a breakpoint on the return line of OnPost
and I hit the Login button from the page - the breakpoint is hit - however the model is null. From Dev Tools however it seems the values from the model are being sent as form data. So I changed the [FromBody]
to [FromForm]
.
However when I run this code and hit the Login button I get the following exception:
InvalidOperationException: Could not create an instance of type 'CarWarehouse.LoginModel'. Model bound complex types must not be abstract or value types and must have a parameterless constructor.
UPDATE
The Login.cshtml page:
@page
@model MyProj.Pages.LoginModel
@{
ViewData["Title"] = "Consent Required";
Layout = "_Layout";
}
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@if (Model.EnableLocalLogin)
{
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Local Login</h3>
</div>
<div class="panel-body">
<form asp-route="Login">
<input type="hidden" asp-for="ReturnUrl" />
<fieldset>
<div class="form-group">
<label asp-for="Username"></label>
<input class="form-control" placeholder="Username" asp-for="Username" autofocus>
</div>
<div class="form-group">
<label asp-for="Password"></label>
<input type="password" class="form-control" placeholder="Password" asp-for="Password" autocomplete="off">
</div>
<div class="form-group">
<button class="btn btn-primary" name="button" value="login">Login</button>
<button class="btn btn-default" name="button" value="cancel">Cancel</button>
</div>
</fieldset>
</form>
</div>
</div>
</div>
}
Note I am using ID Server 4 and just trying too implement similar logic to this repo - https://github.com/IdentityServer/IdentityServer4.Quickstart.UI/tree/master
回答1:
Reference Model Binding in ASP.NET Core: [BindProperties] attribute
Available in ASP.NET Core 2.1 and later. Can be applied to a controller or
PageModel
class to tell model binding to target all public properties of the class:
[BindProperties(SupportsGet=true)]
public class LoginModel : PageModel {
public string ReturnUrl { get; set; }
public bool EnableLocalLogin { get; set; } = true;
public string Username { get; set; }
public string Password { get; set; }
private readonly IIdentityServerInteractionService _interaction;
public LoginModel(IIdentityServerInteractionService interaction) {
_interaction = interaction;
}
public IActionResult OnGet(string returnUrl) {
ReturnUrl = returnUrl;
return Page();
}
public IActionResult OnPost(string button) {
//access properties here which should be populated from form.
// todo - implement
return Page();
}
}
来源:https://stackoverflow.com/questions/57294170/asp-net-core-razor-pages-not-binding-on-post-request