I am in the process of porting an older ASP.NET 4.5 website to ASP.NET Core 3.0, and am running into some issues with the identity Razor pages and how they work.
For example, on the registration page of the application, as shown below, the form is entirely filled out, but when the button is clicked and I hit the breakpoint in the PostAsync()
method of the Register.cs
file, with the Input
model bound, everything is always null
, except for the Enum which I set the initially selected value in the HTML.
Note: Yes I see the typing in the code file. That isn't the issue. I got rid of that after I took the screenshot.
[BindProperty]
public InputModel Input { get; set; }
public class InputModel
{
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[Display(Name = "Gender")]
public Gender Gender { get; set; }
[Required]
[Phone]
[Display(Name = "MobilePhone")]
public string MobilePhone { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { 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; }
}
And in my Startup
file:
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
});
Any thoughts on why the ModelState
is always invalid due the form values always being null?
Here is the HTML of the form:
<form asp-route-returnUrl="@Model.ReturnUrl"
class="form-horizontal push-50-t push-50 form-register"
method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<!-- form entry - first name -->
<div class="form-group">
<div class="col-xs-12">
<div class="form-material form-material-success">
<label asp-for="Input.FirstName"></label>
<input asp-for="Input.FirstName" type="text"
id="register-firstname" name="register-firstname"
class="form-control" placeholder="Enter your first name" />
<span asp-validation-for="Input.FirstName" class="text-danger"></span>
</div>
</div>
</div>
<!-- form entry - last name -->
<div class="form-group">
<div class="col-xs-12">
<div class="form-material form-material-success">
<label asp-for="Input.LastName"></label>
<input asp-for="Input.LastName" type="text"
id="register-lastname" name="register-lastname"
class="form-control" placeholder="Enter your last name" />
<span asp-validation-for="Input.LastName" class="text-danger"></span>
</div>
</div>
</div>
<!-- form entry - gender -->
<div class="form-group">
<div class="col-xs-12">
<div class="form-material form-material-success">
<label asp-for="Input.Gender"></label>
<select class="form-control" asp-for="Input.Gender" id="register-gender" name="register-gender"
placeholder="Please enter Male/Female">
<option selected="selected" value="@Gender.Male">Male</option>
<option value="@Gender.Female">Female</option>
</select>
<span asp-validation-for="Input.Gender" class="text-danger"></span>
</div>
</div>
</div>
<!-- form entry - mobile phone -->
<div class="form-group">
<div class="col-xs-12">
<div class="form-material form-material-success">
<label asp-for="Input.MobilePhone"></label>
<input asp-for="Input.MobilePhone" type="tel"
id="register-mobilephone" name="register-mobilephone"
class="form-control" placeholder="Provide your mobile phone number" />
<span asp-validation-for="Input.MobilePhone" class="text-danger"></span>
</div>
</div>
</div>
<!-- form entry - email -->
<div class="form-group">
<div class="col-xs-12">
<div class="form-material form-material-success">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email"
type="email" id="register-email" name="register-email"
class="form-control" placeholder="Your email address" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
</div>
</div>
<!-- form entry - password -->
<div class="form-group">
<div class="col-xs-12">
<div class="form-material form-material-success">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password"
type="password" id="register-password" name="register-password"
class="form-control" placeholder="Choose a strong password" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
</div>
</div>
<!-- form entry - confirm password -->
<div class="form-group">
<div class="col-xs-12">
<div class="form-material form-material-success">
<label asp-for="Input.ConfirmPassword"></label>
<input asp-for="Input.ConfirmPassword"
type="password" id="register-password2" name="register-password2"
class="form-control" placeholder="Confirm your password" />
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="col-xs-7 col-sm-8">
<label class="css-input switch switch-sm switch-success">
<input type="checkbox" id="register-terms" name="register-terms"><span></span> I agree with terms & conditions
</label>
</div>
<div class="col-xs-5 col-sm-4">
<div class="font-s13 text-right push-5-t">
<a href="#" data-toggle="modal" data-target="#modal-terms">View Terms</a>
</div>
</div>
</div>
<div class="form-group">
<div class="col-xs-12 col-sm-6 col-sm-offset-3">
<button id="register-button" class="btn btn-sm btn-block btn-success" type="submit">Create Account</button>
</div>
</div>
</form>
<!-- END Register Form -->
Update: As Requested by a commenter, here is the request payload as well.