调用POST方法时,ASP.NET MVC模型属性为null

调用POST方法时,ASP.NET MVC模型属性为null,asp.net,asp.net-mvc,asp.net-identity,Asp.net,Asp.net Mvc,Asp.net Identity,在控制器操作中,我有以下调用,userId是一个已知的非空值: return View("ChangePassword", new ChangePasswordBindingModel(userId)); 以下是ChangePasswordBindingModel的定义: public class ChangePasswordBindingModel { private string currentUserId; [Required] [DataType(DataTyp

在控制器操作中,我有以下调用,
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" />
}

问题是,
userid
没有设置为非空值,正如我所想的那样。为什么发送到post方法的模型的
currentUserId
属性不包含该值?我通过在调试期间单步调用
GetUserId()
确认了这一点。

currentUserId
未提交到操作后方法,原因有两个:

  • currentUserId
    不是公共属性
  • 它不存在于
    中,使用
    中的(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" />
    }
    

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


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

    首先将CurrentUserId公开,然后将其放入视图中的隐藏字段中

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

    我认为您需要将currentUserId字段公开,以便对其进行JSON序列化,并将其包含在razor标记中,以便从client@Sam.C是的,谢谢,这是基于有效答案的高级视图。谢谢解释。谢谢帮助。
    result = await UserManager.ChangePasswordAsync(loginChange.CurrentUserId, loginChange.OldPassword, loginChange.NewPassword);
    
     @Html.HiddenFor(x => x.currentUserId )