1. 程式人生 > >ASP.NET MVC/Core表單提交後臺模型二級屬性驗證問題

ASP.NET MVC/Core表單提交後臺模型二級屬性驗證問題

起因

這個是網友在官網論壇的提問:https://fineui.com/bbs/forum.php?mod=viewthread&tid=22237

 

 

重新問題

本著務實求真的態度,我們先來複現這個問題。首先頁面截圖是這樣的:

 

類 MsStudentMajor 有兩個非空屬性 Major2 和 Desc2,如下所示:

public class MsStudentMajor
{
    /// <summary>
    /// 標識
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Name
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// 所學專業
    /// </summary>
    [Required]
    public string Major2 { get; set; }

    [Required]
    public string Desc2 { get; set; }
}

但是頁面上只用到了 Major2,而沒有用到 Desc2:

F.SimpleForm()
    .ID("SimpleForm1")
    .ShowBorder(false)
    .ShowHeader(false)
    .BodyPadding(10)
    .LabelWidth(180)
    .Items(
        F.TextBoxFor(m => m.Name)
            .Label("姓名"),
        F.HiddenFieldFor(m => m.Major)
            .Label("所學專業1"),
        F.DropDownListFor(m => m.StudentMajor.Major2)
            .ID("StudentMajor_Major2")
            //.Name("StudentMajor.Major2")
            .Label("所學專業2")
            .Items(
                F.ListItem()
                    .Text("請選擇")
                    .Value(""),
                F.ListItem()
                    .Text("計算機")
                    .Value("計算機"),
                F.ListItem()
                    .Text("物理")
                    .Value("物理")
            )
            .SelectedValue(Model.StudentMajor.Major2)
        //F.TextBoxFor(m => m.StudentMajor.Desc2)
        //    .Label("描述")
    )

所以在後臺的模型繫結驗證時出錯:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult FormSubmit_btnSave_Click(MsStudent model)
{
    if (ModelState.IsValid)
    {

    }
    return UIHelper.Result();
}

 

除錯分析

遇到問題首先要除錯,看下內部變數是否和預想的有出入。首先看下點選儲存按鈕時客戶端提交的資料:

 

二級屬性是以 StudentMajor.Major2 的形式提交的,後臺接受到的資料:

一切都合情合理,二級屬性也能正確繫結,只不過由於前臺並未告知 StudentMajor.Desc2 的值,所以未能繫結,這也在情理之中。

 

對比測試老版本 FineUIMvc v5.3.0

由於網友在帖子裡提到了老版本 FineUIMvc v5.3.0 是可以正常執行的,所以我們找來了老版本,同樣測試如下:

 

和最新版不同的是,這裡提交的二級屬性名為 StudentMajor_Major2 ,很明顯,後臺模型繫結時不會自動識別這個字串:

所以這裡,模型綁定出來的 StudentMajor == null。自然而然,就不會提示模型繫結失敗,因為未對二級屬性進行有效的繫結處理!

 

很明顯,這個應該是老版本的BUG。如果我們仔細看更新記錄的話,可能看到相關的改進:https://fineui.com/mvc/version/

 

解決問題

既然這是老版本的BUG,而新版本沒有問題。那該如何滿足使用者的這個需求呢?

其實很簡單,ASP.NET MVC/Core提供了一種機制,可以在模型繫結時排除對某些屬性的繫結,如下所示:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult FormSubmit_btnSave_Click([Bind(Exclude = "StudentMajor")]MsStudent model)
{
    if (ModelState.IsValid)
    {

    }
    return UIHelper.Result();
}

注意,這裡的 [Bind(Exclude = "StudentMajor")] 就是告訴ASP.NET MVC/Core 框架在模型繫結時忽略 StudentMajor 屬性。

 

萬事皆有因,萬般皆有果。