2013-08-27 30 views
4

我有一個簡單的強類型視圖,但我似乎無法更新我的表單上的文本框後後。TextBoxFor值後不更新

這裏是我的模型:

public class Repair 
    { 
    public string Number { get; set; }  
    } 

在我看來是一個TextBox:

@Html.TextBoxFor(x => x.Number) 

我想一個帖子到我的控制器之後更新文本框:

[AcceptVerbs(HttpVerbs.Post)] 
     public ActionResult Index(Repair r) 
     { 

      r.Number = "New Value"; 

      return View(r); 

     } 

儘管我將Number設置爲新值,但文本框中的文本不會更改。我究竟做錯了什麼?

回答

16

使用ModelState.Clear()之前設定值

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Index(Repair r) 
{ 
    ModelState.Clear(); //Added here 
    r.Number = "New Value"; 
    return View(r); 
} 
7

將模型返回到ActionResult並返回相同的視圖時,模型對象的值包含在ModelState中。 ModelState是包含有效/無效字段以及實際POST值的信息。如果您想更新模型值,你可以做兩件事情之一:

ModelState.Clear()

ModelState["Number"].Value = new ValueProviderResult("New Value", "New Value", CultureInfo.CurrentCulture)

+0

當嘗試設置的ModelState值,我得到這個錯誤:錯誤無法隱式轉換類型「字符串」到「System.Web.Mvc.ValueProviderResult」 – broke

+0

@broke - 用正確的語法更新它。以下是ValueProviderResult上的MSDN - http://msdn.microsoft.com/zh-cn/library/system.web.mvc.valueproviderresult(v = vs.108).aspx。感謝您的領導! – Tommy

+0

感謝您的更新! – broke

3

從我處理這個問題,我覺得這是由框架中的設計錯誤引起的。國際海事組織:

@Html.TextBoxFor(x => x.Number) 

不應該從ModelState,而是直接從模型中取值。至少這是我的期望,當我改變模型和return View(model)

ModelState.Clear() 

不是一個答案,因爲它進行消毒ModelState擦除的ValidationSummary。從ModelState中刪除密鑰既不好,因爲它會刪除該密鑰的ValidationSummary。

ModelState["Number"].Value = 
new ValueProviderResult("New Value", "New Value", CultureInfo.CurrentCulture) 

是正確的,但太神祕了。因此,在這種情況下,我更傾向於將使用:

<input type="text" name="Number" id="Number" value="@Model.Number"/> 

,而不是

@Html.TextBoxFor(x => x.Number) 
+0

如果你不使用@ Html.TextBoxFor(),你還必須手動添加所有的驗證屬性,這很麻煩 – bgx

2

如果您發現ModelState.Clear()是破壞性太大,你可以針對只有你的項目改變,同時保留與ModelState.Remove()

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Index(Repair r) 
{ 
    r.Number = "New Value"; 
    ModelState.Remove("Number"); 
    return View(r); 
} 

而且剩下的,看來,它並不與物質或者刪除()或清除()你是否調用該方法更新模型之前或之後

0

試試這個。如果你願意,你可以把它放在一個基礎控制器中。它對我來說很好。它使得它如此不顯眼的驗證仍然有效,但模型中的值正好顯示爲預期。

public class BaseController : Controller 
{ 
    public override void OnActionExecuted(ActionExecutedContext context) 
    { 
     ModelState.ToList().Select(x => x.Value).ToList().ForEach(x => { x.AttemptedValue = null; x.RawValue = null; }); 

     // Do a bunch of stuff here if needed. Stuff like validation. 
     base.OnActionExecuted(context); 
    } 
}