延迟加载与序列化
如果使用了延遲加載(Lazy Load),那么,我們就會(huì)在序列化的時(shí)候碰到 延遲加載 變成了 “立即加載” 的問題。這是為什么呢,因?yàn)樾蛄谢鲿?huì)去訪問對象的屬性,這就會(huì)導(dǎo)致屬性的 get 方法內(nèi)的代碼被執(zhí)行起來。
比如,類型:
??? class Test
??? {
??????? public string Name {get; private set;}
??????? public PaperStrategy Paper
??????? {
??????????? get
??????????? {
??????????????? if (paper == null)
??????????????? {
??????????????????? paper = PaperStrategy.GetPaperByTest(this);
??????????????? }
??????????????? return paper;
??????????? }
??????? }
??? }
當(dāng)返回給前臺的時(shí)候,我們只需要返回 Name 屬性就可以,但是,如果我們使用 JavaScriptSerializer (即 ASP.NET MVC 默認(rèn)的 JSON 序列化器)的時(shí)候,序列化器會(huì)默認(rèn)去遍歷全部的屬性,這就會(huì)導(dǎo)致業(yè)務(wù)上并不需要加載的 Paper 被序列化器自動(dòng)加載了。
這是不能容忍的。解決方案有:
一:為屬性加入 [ScriptIgnore]
即:
[ScriptIgnore]
public PaperStrategy Paper
Attribute ScriptIgnore 會(huì)通知 JavaScriptSerializer 不去序列化此屬性,這樣,就不會(huì)執(zhí)行 get 中的代碼;
不過,這帶來一個(gè)問題,如果在別的請求中,又是需要這個(gè)屬性的 Value ,該怎么辦。所以,通過加 Attribute 來指導(dǎo)序列化并不可取。
?
二:構(gòu)筑匿名類型
或者,我們在控制器中構(gòu)筑匿名類型,如下,這就相當(dāng)于存在一個(gè)轉(zhuǎn)換過程,如果屬性較多的話,就相對的編碼煩多。
public class HomeController : SessionController
{
??? public ActionResult Test(int id)
??? {
??????? var test = Session.Get<Test>(id);
??????? return Json(new
??????? {
??????????? test.Name
??????? }, JsonRequestBehavior.AllowGet);
??? }
}
?
三:使用 ViewModel
如果我們覺得以上兩種不合意,則可以強(qiáng)迫自己使用 ViewModel,即創(chuàng)建一個(gè) TestDto,只包含需要序列化的字段,當(dāng)然,這仍然需要一個(gè)類似 二 中的轉(zhuǎn)換。不過,過多的實(shí)體類,不是我喜歡的,所以并不建議此種做法(如想減少實(shí)體類,請參看:減少到處衍生的實(shí)體類)。所以,大部分情況下,推薦的做法還是 構(gòu)筑匿名類型 來達(dá)到 延遲加載 和 序列化 之間的平衡,除非我們有十分強(qiáng)烈的使用 ViewModel 的理由,比如:使用綁定。
?
本文轉(zhuǎn)自最課程陸敏技博客園博客,原文鏈接:http://www.cnblogs.com/luminji/p/3804064.html,如需轉(zhuǎn)載請自行聯(lián)系原作者
總結(jié)
- 上一篇: 关于ViewPager的适配器之——pa
- 下一篇: SAP 物料清单 BOM