2016-08-23 107 views
1

在控制器的行動,我有以下的呼叫,其中userId是一種已知的非空值:ASP.NET MVC模型屬性爲空時,POST方法被調用

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()來確認。

+3

我想你需要使該字段currentUserId公衆它是JSON序列化,還包括它在剃刀標記,以便獲取是從客戶端 –

+0

發送回服務器@ Sam.C是的,謝謝,這是基於有效答案的高層次觀點。 – ITWorker

回答

2

currentUserId未提交後的操作方法,因爲兩個原因:

  1. currentUserId不是公共財產。
  2. 它不存在using (Html.BeginForm區塊內<input>,<textarea><select>標籤。

刪除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屬性的值,如下

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

謝謝,這工作。 – ITWorker

1

currentUserId是私人會員,而不是財產。它不受任何形式領域的束縛。因此,當您通過傳遞非空值爲currentUserId的模型來呈現視圖時,該視圖在客戶端上呈現時會立即丟失該值,因爲它只存在於服務器上的模型中。所以沒有辦法讓它恢復。

您可以創建CurrentUserId屬性,並在視圖中使用Html.HiddenFor()隱藏字段,以便將值發送到客戶端,並在POST期間將其返回。

+0

感謝您的解釋。 – ITWorker

1

首先使currentUserId public,然後把它放在視圖的隱藏字段中。

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

感謝您的幫助。 – ITWorker