• 转:ASP.NET MVC利用TryUpdateModel来做资料更新 (二)


    前言

    第一篇說明了 TryUpdateModel 的簡單的應用,除了可指定更新的欄位之外也可排除更新特定的欄位,而因為可搭配 Metadata 做欄位驗證為資料又做了一層把關,但在 ASP.NET MVC 中我們也很常針對每個的頁面(View)定義專屬的 ViewModel ,而若照個第一篇的寫法會發現欄位無法正確繫結,所以這篇就來教大家如何正確利用 TryUpdateModel 來為我們的 ViewModel 做資料更新 ~

    說明

    首先我們先定義一個 ViewModel 如下:

    public class ProductViewModel
    {
        public Product ViewProduct { get; set; }
    }

    透過 ViewModel 所產生的 View 如下:

    @model MvcTemplete.Models.ProductViewModel
    @{
        ViewBag.Title = "Edit";
    }
    
    @using (Html.BeginForm())
    {
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>Product</legend>
    
            @Html.HiddenFor(model => model.ViewProduct.ProductId)
            <div class="editor-label">
                @Html.LabelFor(model => model.ViewProduct.Name)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.ViewProduct.Name)
                @Html.ValidationMessageFor(model => model.ViewProduct.Name)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.ViewProduct.Ename)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.ViewProduct.Ename)
                @Html.ValidationMessageFor(model => model.ViewProduct.Ename)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.ViewProduct.ModifyUid)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.ViewProduct.ModifyUid)
                @Html.ValidationMessageFor(model => model.ViewProduct.ModifyUid)
            </div>
            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>
    }
    </span>

    接下來我們先看看 Post 回 Controller 時 FormCollection 所接收到集合,如下:

    由上圖可看到在每個 Key 中包含了 ViewProduct 這個前置詞,因為在 ViewModel 裡我們使用了 Prodcut 這個 Model 且命名為 ViewProduct,如果讀者照著上一篇的 TryUpdateModel 的方法,程式會無法成功繫結。

    此時我們可以利用 TryUpdateModel 的另外一個多載來達到資料繫結,程式碼如下:

    if(TryUpdateModel(product, "ViewProduct"))
    {
         db.SaveChanges();
    }

    而若希望更新特定欄位或排除特定欄位,如下:

    if(TryUpdateModel(product, "ViewProduct",new string[] {"Name"},new string[] {"ModifyUid"}))
    {
         db.SaveChanges();
    }

    上面的執行結果僅會更新 Name 欄位,而排除更新 ModifyUid 這個欄位。


    當然上面的方法還是不夠完美,因為我們並沒有搭配 FormCollection 來做資料繫結並排除特定欄位 ,但因為 FormCollection 內的 Keys 是有加上前置詞,導致無法成功繫結並更新,這部份筆者有寫了個轉換的Code來去掉前置詞,如下:

    var Keys = formValue.AllKeys;
    List<string> newKeys = new List();
    foreach (var item in Keys)
    {
        newKeys.Add(item.Replace("ViewProduct.", ""));
    }
    if (TryUpdateModel(product, "ViewProduct", newKeys.ToArray(), new string[] { "ModifyUid" }))
    {
        db.SaveChanges();
    }</string>

    OK !大功告成 ~ 不過不知道有沒有其他大大能針對 FormCollection 有前置詞的部份能有其他更好的解法,因為這個解法只是單純去做字串取代而已(逃)。

    總結

    只能說 TryUpdateModel 在實務上的應用太強大了,如果能善加利用其提供的多載鐵定能應用各種不同的需求,當然還是提醒一下大家使用 TryUpdateModel 時還是要加入「黑名單」或「白名單」,來讓我們的資料更加正確!

  • 相关阅读:
    WordPress The Plus Addons for Elementor插件身份验证绕过漏洞复现分析
    ThinkPHP 5日志文件包含trick
    JavaScript对称数字金字塔(机考)
    css绘制三角箭头
    element-ui table 多列数据动态排序(前后台交互)
    Animate.css
    Normalize.css
    CMake笔记
    时间对齐——用 FFT 加速互相关
    g2o 代码学习—— exp map and log map for SE(3), SIM(3)
  • 原文地址:https://www.cnblogs.com/superfeeling/p/4900083.html
Copyright © 2020-2023  润新知