ASP.. NET MVC模型属性在调用POST方法时为空



在控制器动作中,我有以下调用,其中userId是已知的非空值:

return View("ChangePassword", new ChangePasswordBindingModel(userId));

下面是ChangePasswordBindingModel的定义:

public class ChangePasswordBindingModel
{
    private string currentUserId;
    [Required]
    [DataType(DataType.Password)]
    //[Display(Name = "Current password")]
    public string OldPassword { get; set; }
    [Required]
    //[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "New password")]
    public string NewPassword { get; set; }
    [Required]
    [DataType(DataType.Password)]
    //[Display(Name = "Confirm new password")]
    [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
    public ChangePasswordBindingModel()
    {
    }
    public ChangePasswordBindingModel(string userId)
    {
        this.currentUserId = userId;
    }
    public string GetUserId()
    {
        return this.currentUserId;
    }
}

这是绑定到ChangePassword模型的视图:

@model IdentityDevelopment.Models.ChangePasswordBindingModel
@{ ViewBag.Title = "ChangePassword";
}
@Html.ValidationSummary(false)
<h2>Change Password</h2>

@using (Html.BeginForm("ChangePassword","Account", FormMethod.Post))
{
   @Html.AntiForgeryToken();
    <input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" />
    <div class="form-group">
        <label>Current Password</label>
        @Html.PasswordFor(x => x.OldPassword, new { @class = "form-control" })
    </div>
    <div class="form-group">
        <label>New Password</label>
        @Html.PasswordFor(x => x.NewPassword, new { @class = "form-control" })
    </div>

    <div class="form-group">
        <label>Re-enter New Password</label>
        @Html.PasswordFor(x => x.ConfirmPassword, new { @class = "form-control" })
    </div>
    <!-- <button class="btn btn-primary" type="submit">Save</button> -->
    <input class="btn btn-primary" type="submit" value="Save" />
}

最后,这里是在上面的表单上点击Save的Post方法:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ChangePassword(ChangePasswordBindingModel loginChange)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = null;
        try
        {
            string userid = loginChange.GetUserId();
            result = await UserManager.ChangePasswordAsync(userid, loginChange.OldPassword, loginChange.NewPassword);
        }
        catch (Exception ex)
        {
        }
        if (result != null && result.Succeeded)
        {
            return RedirectToAction("Index");
        }
        else
        {
            if(result != null)
            {
                AddErrorsFromResult(result);
            }
        }
    }
    return View(loginChange);
}

问题是userid没有被设置为非空值,因为我认为GetUserId()会这样做。为什么发送给post方法的模型的currentUserId属性不包含值?我通过在调试期间进入对GetUserId()的调用来确认这一点。

首先将currentUserId设置为public,然后将其放在View的隐藏字段中。

 @Html.HiddenFor(x => x.currentUserId )

currentUserId没有提交给post action方法,原因有两个:

  1. currentUserId不是公共属性
  2. 它不存在于<input>, <textarea><select>标签的using (Html.BeginForm块内。

删除currentUserId并在模型中创建一个名为CurrentUserId的新公共属性。您也不需要GetUserId()方法。您的模型应该如下所示

public class ChangePasswordBindingModel
{
    [Required]
    [DataType(DataType.Password)]
    //[Display(Name = "Current password")]
    public string OldPassword { get; set; }
    [Required]
    //[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "New password")]
    public string NewPassword { get; set; }
    [Required]
    [DataType(DataType.Password)]
    //[Display(Name = "Confirm new password")]
    [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
    public string CurrentUserId { get; set; }
    public ChangePasswordBindingModel()
    {
    }
    public ChangePasswordBindingModel(string userId)
    {
        this.CurrentUserId = userId;
    }
}

并使用HiddenField在视图中包含CurrentUserId

@using (Html.BeginForm("ChangePassword","Account", FormMethod.Post))
{
   @Html.AntiForgeryToken();
    @Html.HiddenFor(x => x.CurrentUserId)
    <input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" />
    <div class="form-group">
        <label>Current Password</label>
        @Html.PasswordFor(x => x.OldPassword, new { @class = "form-control" })
    </div>
    <div class="form-group">
        <label>New Password</label>
        @Html.PasswordFor(x => x.NewPassword, new { @class = "form-control" })
    </div>

    <div class="form-group">
        <label>Re-enter New Password</label>
        @Html.PasswordFor(x => x.ConfirmPassword, new { @class = "form-control" })
    </div>
    <!-- <button class="btn btn-primary" type="submit">Save</button> -->
    <input class="btn btn-primary" type="submit" value="Save" />
}

在post action方法中,您可以获得CurrentUserId属性的值,如下所示

result = await UserManager.ChangePasswordAsync(loginChange.CurrentUserId, loginChange.OldPassword, loginChange.NewPassword);

currentUserId是私有成员,而不是属性。而且它没有绑定到视图中的任何表单字段。因此,当您通过传递具有currentUserId的非空值的模型来渲染视图时,当视图在客户端上渲染时,该值立即丢失,因为它只存在于服务器上的模型中。所以没有办法把它拿回来。

您可以创建一个CurrentUserId属性,并在您的视图中使用Html.HiddenFor()有一个隐藏字段,以便将值发送到客户端,并在POST期间返回

相关内容

  • 没有找到相关文章

最新更新