[Asp .Net MVC] ModelState 機制

今天在幫同事解問題的時候,碰到一個明明已經回傳一個新的Model 給前端了,但是資料依然是舊的,原來是ModelState影響了結果。

Code 如下:

@model TestProject1.Model.EditModel

@using (Html.BeginForm("Submit", "Default1"))
{
    @Html.TextAreaFor(x => x.Column1)

    <input  type="submit" value="Submit"/>
}

首先View 很簡單,就是一個TextArea 與 一個Submit Button,Form Submit 會跑到後端的Submit Action 上。

    public class Default1Controller : Controller
    {
        public ActionResult Index(EditModel model)
        {
            return PartialView("Index",model);
        }

        public ActionResult Submit(EditModel model)
        {
            model.Column1 = "Submit Change";
            return Index(model);
        }
    }

再來是Controller ,一進來就是到 Index 然後 Return 「Index」這個 Partial。

畫面如下(沒有美工請見諒):


理論上Submit 後 TextArea 的值會被改成「Submit Change」,但是卻沒有,永遠會變成你輸入的值;

ex:

我在畫面上打了「Harry Test」,再按下 Submit ,也確定Model Column1 的值有被改成「Submit Change」,但畫面就是依然顯示「Harry Test」。後來發現是 ModelState 在搞鬼!Model State 會在我們Model Binding 時幫我們紀錄前端傳回來的值,同時會幫我們儲存Model 的驗證狀態,而前端會優先顯示Model State 的值,所以不管你後端在ViewModel 如何更改都是沒有用的,唯一能做的就是Clear ModelState,如下:

    public class Default1Controller : Controller
    {
        public ActionResult Index(EditModel model)
        {
            return PartialView("Index",model);
        }

        public ActionResult Submit(EditModel model)
        {
            model.Column1 = "Submit Change";
            ModelState.Clear();
            return Index(model);
        }
    }

加入了「ModelState.Clear()」即可正常顯示。

後記:

後來對這個機制感到十分不解。

理論上除非是Model 驗證不通過的情況下,不然在Model 驗證通過的情形下,只要我們給了新的Model 就應該幫我們清掉ModelState,在Msdn上跟大家討論了一下,結論是:去建議微軟吧!

參考:認識Model-ModelState

Msdn:ModelState為何不會自行Clear!?