前言

第一篇說明了 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 時還是要加入「黑名單」或「白名單」,來讓我們的資料更加正確!

转: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. HDU 4507 (鬼畜级别的数位DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507 题目大意:求指定范围内与7不沾边的所有数的平方和.结果要mod 10^9+7(鬼畜の元凶) 解题 ...

  2. COJ1013 : WZJ的数据结构(十三)

    这道题有这样一个解法: 首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去并将每条边把哪条边弹了出去记录下来:ntr[i] = j,特别地,要是没有弹出边,ntr ...

  3. oracle系列--第三篇 Oracle的安装

    在安装之前,我先说说我的电脑的配置: OS : Windows 7 32bit CPU : 3GHz Memory : 2GB Desk : 320GB ======================= ...

  4. html5shiv.js-让IE浏览器支持HTML5标准

    兼容性IE8及以下IE版本 浏览器IE8及以下IE版本对HTML5标签的支持是有限的,我们可以通过在网页中添加脚本的方式来解决目前IE浏览器对HTML5支持的问题. <!–[if IE]> ...

  5. PHP+jQuery 注册模块的改进之三:使用 Smarty3

    Smarty3.1X( 最新版本 3.1.19) 比起Smarty2.x修改了不少特性.我把这个模块使用Smarty3.1.18 ( 下载地址http://www.smarty.net/files/S ...

  6. Sublime Text初识

    一 基础安装1. 安装Package Control使用快捷键ctrl+`,调出输出窗口, 然后输入官网提供的代码, 获取代码地址:https://packagecontrol.io/installa ...

  7. uitextfield输入字符限制

    -(UITextField*)createField:(NSString*)placeholder andTag:(int)tag andFont:(double)font{ UITextField ...

  8. 从StackOverflow来的值得回味的编程观点

    从StackOverflow来的值得回味的编程观点 很多有意思的话语 在 2012年06月08日 那天写的     已经有 4148 次阅读了 感谢 参考或原文 www.csdn.net   服务器君 ...

  9. PHP面向对象程序设计的61条黄金法则

    PHP面向对象程序设计的61条黄金法则   你不必严格遵守这些原则,违背它们也不会被处以宗教刑罚.但你应当把这些原则看成警铃,若违背了其中的一条,那么警铃就会响起 . ----- Arthur J.R ...

  10. 页面静态化2 --- 使用PHP缓存机制来完成页面静态化(上)(ob_flush和flush函数区别用法)

    我们可以使用PHP自带的缓存机制来完成页面静态化,但在这里,需要说明一点,仅靠PHP缓存机制并不能完美的解决页面静态化,往往需要和其他页面静态技术(通常是伪静态技术)结合使用 例子: 当访问一个页面时 ...