前言

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

說明

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

  1. public class ProductViewModel
  2. {
  3. public Product ViewProduct { get; set; }
  4. }

透過 ViewModel 所產生的 View 如下:

  1. @model MvcTemplete.Models.ProductViewModel
  2. @{
  3. ViewBag.Title = "Edit";
  4. }
  5.  
  6. @using (Html.BeginForm())
  7. {
  8. @Html.ValidationSummary(true)
  9. <fieldset>
  10. <legend>Product</legend>
  11.  
  12. @Html.HiddenFor(model => model.ViewProduct.ProductId)
  13. <div class="editor-label">
  14. @Html.LabelFor(model => model.ViewProduct.Name)
  15. </div>
  16. <div class="editor-field">
  17. @Html.EditorFor(model => model.ViewProduct.Name)
  18. @Html.ValidationMessageFor(model => model.ViewProduct.Name)
  19. </div>
  20. <div class="editor-label">
  21. @Html.LabelFor(model => model.ViewProduct.Ename)
  22. </div>
  23. <div class="editor-field">
  24. @Html.EditorFor(model => model.ViewProduct.Ename)
  25. @Html.ValidationMessageFor(model => model.ViewProduct.Ename)
  26. </div>
  27. <div class="editor-label">
  28. @Html.LabelFor(model => model.ViewProduct.ModifyUid)
  29. </div>
  30. <div class="editor-field">
  31. @Html.EditorFor(model => model.ViewProduct.ModifyUid)
  32. @Html.ValidationMessageFor(model => model.ViewProduct.ModifyUid)
  33. </div>
  34. <p>
  35. <input type="submit" value="Save" />
  36. </p>
  37. </fieldset>
  38. }
  39. </span>

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

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

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

  1. if(TryUpdateModel(product, "ViewProduct"))
  2. {
  3. db.SaveChanges();
  4. }

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

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

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


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

  1. var Keys = formValue.AllKeys;
  2. List<string> newKeys = new List();
  3. foreach (var item in Keys)
  4. {
  5. newKeys.Add(item.Replace("ViewProduct.", ""));
  6. }
  7. if (TryUpdateModel(product, "ViewProduct", newKeys.ToArray(), new string[] { "ModifyUid" }))
  8. {
  9. db.SaveChanges();
  10. }</string>

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

總結

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

转:ASP.NET MVC利用TryUpdateModel来做资料更新 (二)的更多相关文章

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

    前言有使用 ASP.NET MVC 的朋友们一定多多少少有听过 TryUpdateModel,之前就看了很多有关它的文章,但在专案实务上都未曾实际使用过,而 TryUpdateModel 不仅能利用 ...

  2. ASP.NET MVC 利用ActionFilterAttribute来做权限等

    ActionFilterAttribute是Action过滤类,该属于会在执行一个action之前先执行.而ActionFilterAttribute是 MVC的一个专门处理action过滤的类.基于 ...

  3. ASP.NET MVC利用PagedList分页(二)PagedList+Ajax+JsRender

    (原文) 昨天在ASP.NET MVC利用PagedList分页(一)的 最后一节提到,一个好的用户体验绝对不可能是点击下一页后刷新页面,所以今天来说说利用Ajax+PagedList实现无刷新(个人 ...

  4. 转:【译】Asp.net MVC 利用自定义RouteHandler来防止图片盗链

    [译]Asp.net MVC 利用自定义RouteHandler来防止图片盗链   你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你 ...

  5. [ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面

    原文:[ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面 随着最终用户对用户体验需求的不断提高,实际上我们很多情况下已经在按照桌面应用的标准来设计Web应用,甚至很多Web页面本身就 ...

  6. 返璞归真 asp.net mvc (1) - 添加、查询、更新和删除的 Demo

    原文:返璞归真 asp.net mvc (1) - 添加.查询.更新和删除的 Demo [索引页] [源码下载] 返璞归真 asp.net mvc (1) - 添加.查询.更新和删除的 Demo 作者 ...

  7. ASP.NET MVC 使用TryUpdateModel 更新的技巧

    有使用 ASP.NET MVC 的朋友應該會對於 TryUpdateModel 有一定的認知,他不但可以利用 Metadata 來做欄位的驗證確保資料的正確性,也可以指定更新的條件以及不更新的條件來達 ...

  8. ASP.NET MVC 利用IRouteHandler, IHttpHandler实现图片防盗链

    你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你的服务器带宽.下面这种方法可以告诉你如何在ASP.NET MVC中实现一个自定义Ro ...

  9. [ASP.NET MVC] 利用自定义的AuthenticationFilter实现Basic认证

    很多情况下目标Action方法都要求在一个安全上下文中被执行,这里所谓的安全上下文主要指的是当前请求者是一个经过授权的用户.授权的本质就是让用户在他许可的权限范围内做他能够做的事情,授权的前提是请求者 ...

随机推荐

  1. 在桌面chrome中调试android设备中的web页面

    准备工作 1, 桌面版chrome 2, Android设备(安装有chrome浏览器) 3, Android-sdk Android-sdk安装及设置 SKD安装 从http://developer ...

  2. 达成成就:排名和AC数相同

    233333 纪念一下.(268会不会是幸运数字呢0.0

  3. COJ976 WZJ的数据结构(负二十四)

    试题描述 输入一个字符串S,回答Q次问题,给你l,r,输出从Sl--Sr组成的串在S中出现了多少次. 输入 第一行为一个字符串S.第二行为一个正整数Q.接下来Q行每行为l,r. 输出 对于每个询问,输 ...

  4. 【转载】Erlang 中 link 和 monitor 的区别

    Link and Monitor differences 原文地址 Introduction link/1 and monitor/2 are 2 different ways of notifyin ...

  5. mysql5.6安装

    mysql5.6安装 #卸载原有的mysqlyum remove mysql*ls /etc/my.cnf*mv /etc/my.cnf* /tmp/ #安装依赖包yum install make c ...

  6. java---一元二次方程练习

    public class wu{ public static void main(String[] args){ int a = 2,b = 1, c = 0,d = b*b-4*a*c if (a ...

  7. Task Scheduler Error and Success Constants (Windows)

    If an error occurs, the Task Scheduler APIs can return one of the following error codes as an HRESUL ...

  8. Win2003+Powershell2.0下无权限解锁账号

    在GE环境下,我通过图形界面ADUC可以解锁一个员工账号,但是通过powershell命令却提示权限不足,咋回事?   PS C:\Users\814072> Unlock-ADAccount ...

  9. 以http形式启动uwsgi服务

    uwsgi yourfile.ini # 配置文件 [uwsgi] http = 127.0.0.1:3106 socket = 127.0.0.1:3006 chdir = /www/student ...

  10. 解决电脑访问Discuz!手机版(支持触屏版)

    discuz电脑访问手机版的方法现在需要来修改一下2个文件,即可用电脑浏览discuz的手机版本:找到./source/function/function_core.php 文件,查找 : funct ...