zoukankan      html  css  js  c++  java
  • 使用Mono.Cecil辅助ASP.NET MVC使用dynamic类型Model

    使用Mono.Cecil辅助ASP.NET MVC使用dynamic类型Model

    2011-09-06 00:21 by 老赵, 8645 visits

    这也是之前在珠三角技术沙龙上的示例之一,解决的是在ASP.NET MVC使用dynamic类型Model时遇到的一个真实问题。

    C# 4编译器支持dynamic类型,因此在编写页面模板的时候自然就可以把它作为视图的Model类型。

    表现层的需求很容易改变,因此dynamic类型的Model可以减少我们反复修改强类型Model的麻烦,再配合匿名类型的使用,可谓是动静相宜,如鱼得水。

    不过,如果把一个匿名类型直接作为Model交给视图去使用,在默认情况下会抛出异常。我们可以用Mono.Cecil来改变这一情况。

    在视图中使用dynamic类型Model

    我们先来重现这个问题。创建一个使用C# 4的ASP.NET MVC网站,添加如下的Controller,其中把匿名类型作为视图Model:

    public class HomeController : Controller
    {
        public ActionResult Index(string title = "<<Default>>")
        {
            return View(new { Title = title });
        }
    }

    并定义一个Index.aspx作为视图模板,Model类型作为dynamic,并用到Title:

    <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
    
    <!DOCTYPE html>
    <html>
    <head runat="server">
        <title>Index</title>
    </head>
    <body>
        <h1><%: Model.Title %></h1>
    </body>
    </html>

    按理来说,这么做应该一切正常,但是运行之后便会提示说Model上找不到Title成员:

    dynamic model load failed

    这又是什么原因呢?

    访问级别与成员

    在C# 4出现之前,我们也完全可以构造一个Model类型作为视图的模型,例如:

    public class IndexModel
    {
        public string Title { get; set; }
    }

    使用这种做法便完全可以正常运行通过了。那么为什么具体类型能够正常工作,而匿名类型却失败了呢?“按常理推断”它们不都是普通的类型,然后访问它们的属性吗?我们用ILSpy查看使用匿名类型编译后的结果,可以发现匿名类型与上面的IndexModel有一个重要的不同之处:

    internal anonymous types

    由于是“匿名类型”,显然它的访问级别应该是internal的,这样它就能对外“隐藏”起来了。但是这就给ASP.NET MVC的视图带来了麻烦。因为ASP.NET MVC的视图会在运行时动态地编译aspx为额外的dll,因此它是无法访问到Controller所在程序集的internal成员的。经试验,如果我们将之前的IndexModel的访问级别修改为internal便会得到相同的结果。

    额外提一句,类似的代码在Mono下却可以运行通过。这意味着在动态访问对象成员的时候,Mono和.NET在访问级别方面的检查是有所不同的。虽然在这个情景里Mono更方便,但理论上说,.NET的做法实则更合理。

    使用NuGet安装Mono.Cecil

    Mono.Cecil是Mono的组件之一,用来编辑.NET程序集文件。我们可以用它来打探一个.NET程序集内部的结构,就像反射那样,只不过并不需要将程序集加载进来,Mono.Cecil只是读取文件物理内容而已。例如,上图所用的ILSpy便用到了Mono.Cecil。更重要的是,Mono.Cecil可以修改并保存程序集,这便可以让我们实现各种奇形怪状的要求。像这篇文章所提到的,只不过是小试牛刀而已。

    Mono和.NET是二进制兼容的,因此我们可以直接把Mono下的Mono.Cecil.dll复制并引用到.NET程序里。不过这么做还是麻烦了,如今在.NET平台上使用各种组件已经有更方便的做法:使用包管理器。.NET平台下的包管理器叫做NuGet,是由SubText的作者,后来被微软聘用作ASP.NET MVC程序经理的Phil Haack带头开发的开源项目。NuGet提供了Visual Studio的扩展,同时也有基于PowerShell的命令行。这里我们就从Visual Studio的扩展开始使用吧。

    创建一个名为PublicAnonymous的控制台项目,并选择Reference - Manage NuGet Packages:

    manage nuget packages

    搜索Mono.Cecil,并安装即可:

    install mono.cecil via nuget

    NuGet会自动处理组件之间的依赖及项目的配置,您也可以自己把玩一番。

    使用Mono.Cecil修改程序集

    有了Mono.Cecil我们便可以修改程序集了,只需数行代码:

    static void Main(string[] args)
    {
        var asmFile = args[0];
        Console.WriteLine("Making anonymous types public for '{0}'.", asmFile);
    
        var asmDef = AssemblyDefinition.ReadAssembly(asmFile, new ReaderParameters
        {
            ReadSymbols = true
        });
    
        var anonymousTypes = asmDef.Modules
            .SelectMany(m => m.Types)
            .Where(t => t.Name.Contains("<>f__AnonymousType"));
    
        foreach (var type in anonymousTypes)
        {
            type.IsPublic = true;
        }
    
        asmDef.Write(asmFile, new WriterParameters
        {
            WriteSymbols = true
        });
    }

    首先,从参数中获取需要修改的程序集名称,找到所有的匿名类型,并将其访问级别设为Public后保存。保存的时候将WriteSymbols参数设为true,这样它也会同时修改pdb文件——这很重要,否则修改后的程序集无法和pdb文件内容相对应,便无法调试了。换句话说,Mono.Cecil也能正确处理pdb文件。

    最后,只要在ASP.NET MVC网站编译时使用这个项目即可,只需配置一下它的Post Build事件:

    post build scripts

    再次编译并运行程序,即可得到正确结果。再拿ILSpy来检查一番:

    public anonymous types

    总结

    在沙龙上,有朋友问我怎么样可以成为一个高级.NET技术人员。我不知道“如何成为”,但我想,了解整个生态环境的发展情况,了解.NET的优势及不足,甚至能够了解相关领域其他技术方向的发展态势,应该是优秀.NET程序员的特质之一吧。

    而Mono便是.NET生态环境的重要组成部分。

    Creative Commons License

    本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

    ADD YOUR COMMENT

    93 条回复

    1. 张志敏

      链接

      张志敏 2011-09-06 06:53:19

      明显是在炫耀技术, 虽然可以这样做,但是看不出这样做有什么优点,为啥不用 dynamic 的 ViewBag 呢?

      Mono.Cecil可以做的事情很多, 比如在 Silverlight 下, 可以在客户端分析程序集的引用情况, 进而做出按照 dll 进行按需加载的导航框架。

      http://www.cnblogs.com/beginor/archive/2011/04/29/2032563.html

    2. 老赵
      admin

      链接

      老赵 2011-09-06 08:43:15

      @张志敏

      看不出优点?这里的优点就是我能用匿名对象使用Model,保证开发人员体验:

      1 View(new {
      2     Data = ...,
      3     Text = ...,
      4     Sample = ...
      5 });

      而不需要:

      1 var model = new ViewBag();
      2 model.Data = ...;
      3 model.Text = ...;
      4 model.Sample = ...;
      5 View(model);

      在我看来,使用匿名对象对于开发人员是很直观的做法,必须支持。

    3. Roy
      114.245.220.*

      链接

      Roy 2011-09-06 09:02:00

      老赵这个修改是不是把GC里的库给改了?虽然改个访问权限也没什么,但是也会影响其他程序吧?

      我看你那个评论的差不多,呵呵

      1 View(new ViewBag{
      2     Data = ...,
      3     Text = ...,
      4     Sample = ...
      5 });

      这样是不是也行?

    4. xgluxv
      101.44.211.*

      链接

      xgluxv 2011-09-06 09:04:56

      传给View的Model和ViewBag应该在作用上是有分类的 他们分别负责不同的数据传递的吧。

      还有貌似ViewBag不是像老赵这么用的。应该直接:

      1 ViewBag.Data=....;
      2 ViewBag.Text=...;

      也不需要用View(ViewBag)传递。

    5. 张志敏

      链接

      张志敏 2011-09-06 09:07:32

      @老赵

      不要修改人家的名字好不好,另外,ViewBag 是这样用的

      http://davidhayden.com/blog/dave/archive/2011/01/19/ViewBagAspNetMvc3.aspx

    6. Terry Sun
      222.128.6.*

      链接

      Terry Sun 2011-09-06 09:10:08

      1 View(new ViewBag(){
      2     Data = ...,
      3     Text = ...,
      4     Sample = ...
      5 });

      1 View(new {
      2     Data = ...,
      3     Text = ...,
      4     Sample = ...
      5 });

      相比有何优点,第一种更直观不是

    7. 老赵
      admin

      链接

      老赵 2011-09-06 09:52:04

      @张志敏

      如果ViewBag是这样用的,那么我倒愈发觉得使用匿名对象传递Model的做法方便了。

    8. 老赵
      admin

      链接

      老赵 2011-09-06 09:53:25

      @Terry Sun

      第一种是指哪种?其实无论哪种更好,可能有个人口味在里面。就像我觉得匿名对象可以省下new一个具体对象,这样才好。

      而且就算不论口味,使用匿名类型的对象是一种很直观的使用方式,在我看来也是必须要支持的。而且支持以后也没有影响你使用ViewBag,甚至你可以这么做了:

      1 ViewBag.Post = new {
      2     Title = ...,
      3     Content = ...
      4 };

      你一样会遇到问题,还是要我这种做法来解决。

    9. xgluxv
      101.44.211.*

      链接

      xgluxv 2011-09-06 09:55:09

      看到微薄里的评论 果然水平太低 没有领会到老赵的深意 把我前面的留言删掉吧

    10. 老赵
      admin

      链接

      老赵 2011-09-06 09:55:37

      @Roy

      什么叫做把GC里的库也修改了?这个类型就是给视图用的,为什么会影响其他程序?

    11. fengyjmax
      183.62.146.*

      链接

      fengyjmax 2011-09-06 09:56:31

      在编译时去修改程序集,嗯,是个不错的思路,可以去做很多有意思的事情。

    12. 两会
      58.23.255.*

      链接

      两会 2011-09-06 10:34:29

      强大的Mono.Cecil……

    13. oyster
      116.228.221.*

      链接

      oyster 2011-09-06 12:46:55

      ViewBag 也没法访问第二级匿名类的属性。 如:ViewBag.P=new {title="hello"};

      view中 访问 ViewBag.P.title 一样出错,所以我觉得老赵这个还是很有价值的。

      而且也不麻烦嘛~

    14. James Zhang

      链接

      James Zhang 2011-09-06 15:06:42

      既然是匿名类型,那么在AssemblyInfo.cs 指定 InternalsVisibleTo("xxxx") 这样应该也可以解决吧。

    15. 老赵
      admin

      链接

      老赵 2011-09-06 15:23:56

      @James Zhang

      这也行,只是ASP.NET的aspx自动编译出来的程序集没地方加这个。

    16. RexZhao
      147.8.179.*

      链接

      RexZhao 2011-09-06 17:58:54

      修改效果很漂亮,修改方式感觉有些难以接受。不过很欣赏你的高质量博文。

    17. 老赵
      admin

      链接

      老赵 2011-09-06 21:41:41

      @RexZhao

      修改方式为什么令人难以接受?

    18. mathgl
      203.218.7.*

      链接

      mathgl 2011-09-06 23:27:52

      说php总会说facebook...貌似facebook也用了很多erlang捏....

    19. chensheng
      60.29.35.*

      链接

      chensheng 2011-09-07 08:58:33

      这样做有点为为之而为之的意思,个人感觉还是没必要 只是个人习惯而已。个人观点view继承的Model最好是强类型寓意明确的,而匿名如果用在传递 数据上 应该实用些简单的数据,例如“title,validate”之类。(如果你的view数据足够的简单 也可以这样做~~完全不用Model 一段脚本 call 一个 action返回json效果应该比这样更简洁,无需Model之类),dynamic是在程序运行的时候动态解析的,应该需求针对业务背景的时候再用(runtime)。可能是为了显示Mono的强大吧,所以哪都想试上几分。浅见!

    20. 老赵
      admin

      链接

      老赵 2011-09-07 09:37:57

      @chensheng

      有个东西需要搞清楚的是,我是先遇到了这个问题,再用Mono.Cecil去解决,而不是想要用Mono.Cecil再去搞出这么个问题来。除非你给出一种更好的做法,那说不定我是“为了显示Mono强大”。事实上我之前也写过文章来用另外的方法解决这个问题,没有现在的好。

      至于View的Model是强类型的,我以前也用过,只是麻烦而已,这是个人的选择。我现在更倾向于在表现层这里使用动态类型的,无数人也和我有相同的选择。

      至于你说的简单的数据,JSON之类的,就实在让我摸不着头脑了。JSON是一种最终表现形式,输入View,而我现在的View是HTML。在得到无论是JSON还是HTML之前都需要最终的内存里的“数据”,这个“数据”才是这里的“匿名对象”,还没有到表现形式这个阶段。这部分概念也必须搞清楚。

    21. AntiGameZ
      121.229.64.*

      链接

      AntiGameZ 2011-09-08 01:15:47

      不知道老赵有没有看过Rob Conery的Massive ORM:https://github.com/robconery/massive

      你所讨论的问题,恰恰是我使用Massive以来,一直困扰着我的问题。

      看了上面的评论,忍不住还是得留下一个深深的感谢。

    22. 梁利锋
      114.252.66.*

      链接

      梁利锋 2011-09-08 16:52:20

      要访问其它程序集的internal成员,用友元就可以了。

    23. 老赵
      admin

      链接

      老赵 2011-09-08 21:23:20

      @梁利锋

      是不是都没看这里是什么场景啊?您来个友元看看?

    24. 浙江油烟机
      125.115.49.*

      链接

      浙江油烟机 2011-09-09 14:00:41

      你通不通过我的留言,我就在那里,不悲不喜

    25. StrongBird
      168.159.144.*

      链接

      StrongBird 2011-09-09 17:56:28

      虽然老赵的方式的确是蛮有意思,但是我同意用ViewBag的方式更加贴切。 因为当你定义一个匿名类型的时候,你就应该默认认为它不该暴露出来,它就应该是Internal的。ViewBag正是做了这一层的包装,然后让外部程序集可以访问。但是手动改程序集,未免和设计的初衷有违背。 当然,对于用Mono.Cecil的这个过程还是让我受益匪浅,有了Mono.Cecil的确可以创造出许多新思路来。

    26. 老赵
      admin

      链接

      老赵 2011-09-09 23:30:33

      @StrongBird

      现在我用匿名类型就是想方便地暴露出公开的信息,没有人说过匿名类型就一定是不暴露出去的。

    27. StarOcean
      202.107.218.*

      链接

      StarOcean 2011-09-10 22:42:42

      赵老师好! 前面说的:“还有说改动下数据库就到处改定义,只能说明你落后于实践很多年了” 我是asp.net新手,现在还是改了数据库就得改model,当然是用自动生成器 请问除了文中的办法有什么办法可以不用改model呢。。

    28. 老赵
      admin

      链接

      老赵 2011-09-10 23:36:07

      @StarOcean

      就是代码自动生成器啊,“到处改定义”是指“手动”的,自动的当然就不算到处改了。

      还有,文中的办法跟这个其实一点关系也没有……

    29. StarOcean
      115.218.85.*

      链接

      StarOcean 2011-09-12 17:58:10

      哈哈,3Q,其实文章没大看懂。评论倒是都看了,原来就是指生成器呢~

    30. gakaki
      180.159.223.*

      链接

      gakaki 2011-09-15 09:07:24

      其实这就是ruby py lua js等语言提成的 meta programming 动态时修改运行时修改程序代码。。。

      其实java流涌aop之流的技术就是为了克服静态语言的弱点

      光看代码html +css 开发window 8 要比sl + c#代码量要少

      但还是要编译js 感觉有点失去了js在浏览器里的爽快感还要速度

      xaml布局不怎么样还有。。。。

      还有windows8里的sdk C#貌似直接支持async 语法了 C#5的

    31. gakaki
      180.159.223.*

      链接

      gakaki 2011-09-15 09:12:57

      如果楼上的同学们 有同时用 java 流 mvc框架 php的框架和ruby on rails的框架,就知道老赵为啥这么做了

      除了ror 其他都是assign php的smarty template,asp.net mvc 用viewbag来吧数据放进去

      ror 直接实例变量就可以,你说从语言层面来说哪个爽

      这样我可以省掉一个 assign语句了。。。

    32. zzfff
      61.184.206.*

      链接

      zzfff 2011-09-15 22:10:10

      @mcpssx

      其实windows需要面对的是两个基本独立的群体:生产群体与消费群体。前者的典型动作是用键盘鼠标操弄着office、企业应用客户端,后者的典型动物是抚摸着愤怒的小鸟;前者的最佳环境是desktop mode,后者的最佳环境是metro mode。

      苹果是消费电子公司,主打后一个群体;微软是软件公司,超大胃口的软件公司,两个群体通吃。

      老赵在IBM,肯定还是面对的是生产群体,基本可以忽视metro那一套。

      简便现在做企业应用客户端,出于各方面的妥协,也许winform是最佳选择。

      (你FUD得比较有水平,我比较佩服)

    33. zzfff
      61.184.206.*

      链接

      zzfff 2011-09-15 22:11:20

      即便现在做企业应用客户端

    34. zzfff
      61.184.206.*

      链接

      zzfff 2011-09-15 23:13:08

      企业应用客户端可能是:HTML+JS,浏览器中的silverlight,standalone app(wpf,winform),没用过metro,没想象力。

      企业应用服务端:asp.net,wcf,wf,appfabric,sharepoint server,biztalk server,sql server...开发只有.net一条路,和WinRT半毛钱关系都没有。

    35. zzfff
      61.184.206.*

      链接

      zzfff 2011-09-15 23:17:52

      企业应用客户端还可能是:office + VSTO

    36. mathgl
      218.103.184.*

      链接

      mathgl 2011-09-16 00:23:04

      有水平的FUD还是fud嘛...这么好精力和老赵较劲,为啥不和Miguel de Icaza 说说看呢?

    37. 麦子
      114.80.133.*

      链接

      麦子 2011-09-16 17:25:51

      支持老赵,我也喜欢直接new一个匿名对象

    38. 老赵
      admin

      链接

      老赵 2011-09-17 12:03:51

      @gakaki: 但还是要编译js 感觉有点失去了js在浏览器里的爽快感还要速度

      编译不编译,跟开发人员又无关。现在的JS不编译吗?只是你不知道它在编译而已。

    39. 老赵
      admin

      链接

      老赵 2011-09-17 16:08:40

      说起来我做人真是太有准则了,博客上不删评论,微博上不加黑名单,果然就容易被人找上门来啊。真是比不上行业里的好多高手,指点江山。

    40. zzfff
      61.184.206.*

      链接

      zzfff 2011-09-17 19:41:58

      这是个消费横行、消费至死的时代,乔布斯是消费主义的符号。大家快去研究WinRT吧,说不定会演绎一曲“愤怒的大鸟”的传奇呢。

      从80年代个人电脑的兴起,到新世纪消费电子的流行,苹果无疑是革命先行者,也是微软的精神导师。90年代学生打败老师的一幕会在10年代重演吗?“历史总是惊人的相似”这一魔咒会失灵吗?师母已呆!

      老赵的小宇宙快爆发了,难道是世界末日的先兆?

    41. mathgl
      116.10.98.*

      链接

      mathgl 2011-09-18 13:51:47

      @老赵: 你完全就没搞懂Mono现在是在做什么。Mono从来没有要在Windows客户端上搞什么,比如WPF之类的,Mono从来就没有搭理过,那么现在Windows提供了Metro客户端有什么问题?Mono照样走服务器端发展路线,以及传统的.NET Core。至于C++,VB,JS之类的无所谓,Mono从来就是只搞C#。

      我怎么感觉现在用mono的人 大多是做移动开发的呢? 在server应用Mono 好像没什么很令人深刻的例子。

    42. junxy
      220.168.63.*

      链接

      junxy 2011-09-22 10:04:36

      前两天在项目中我还碰到这个问题,还以为MVC3不支持这种model,看到这篇文章后都明白了。

      当时在stackoverflow找了个比较死的方法:返回一个List<dynamic>视图model,里面手动添加的一些ExpandoObject。。。

    43. zhuisha
      219.142.54.*

      链接

      zhuisha 2011-09-26 13:54:20

      @mcpssx

      你看了那么多的WinRT Session当真是勤奋,但是莫非你就没看见大多数Session的第一句介绍就是,这WinRT这玩意儿是用来替代Win32的,是Windows的另一个API,只不过吸收了.NET的思想,搞得面向对象了点,并且Win32仍然支持.实在搞不明白,你让WinRT跟.NET纠结啥呢?

      至于说你说的技术交流,我觉得一个基本问题,就是不能光低头拉车,还要抬头看路,一些要过时的技术有什么必要深入讲解?以前那些winform之类的文章再深入不过是浪费大家的时间而已。

      WinForm做企业开发没觉得有啥不爽啊,莫非你要做个进销存也用C++高来搞去?

    44. 韦恩卑鄙 @waynebaby

      链接

      韦恩卑鄙 @waynebaby 2011-09-28 11:27:58

      可乐死我了 哈哈哈 @mcpssx 看了那么多Build 的视频 没有注意到按照 Windows RT APP方式 不能运行在Desktop和网页中么? 这是一套平板触摸SDK拉 WPF和sl会一直活得很好的 哈哈哈

    45. 韦恩卑鄙 @waynebaby

      链接

      韦恩卑鄙 @waynebaby 2011-09-28 11:34:29

      老赵 这篇我来得比较晚

      用这个方法 在View里只能用 dynamic吧

      俺是非常懒的人,俺想问 有没有希望再进一步 在view<>里面直接使用这个匿名类型作为泛型参数 连智能提示都搞出来呢

      或者说 这是compile as service 的时候才有希望的事情了?>_<

    46. 老赵
      admin

      链接

      老赵 2011-09-28 13:05:05

      @韦恩卑鄙

      这个其实比较难吧,因为View自己又不知道自己的Model是谁提供的,View和Action又没法对应起来。以前有智能提示,是因为View已经标记了Model类型。

    47. xiangzhuyuan
      221.217.48.*

      链接

      xiangzhuyuan 2011-10-07 10:44:19

      看来老赵有点忙啊 !好久不更新!

    48. 韦恩卑鄙 @waynebaby

      链接

      韦恩卑鄙 @waynebaby 2011-10-08 18:06:16

      因为View自己又不知道自己的Model是谁提供的 的确是这样。

      其实我们一般情况下是不会让一个View接受多种类型的输出的 如果我们输出了 new{a=1,b=2} (类型 dasha) 我们其实是希望让View能够写到view中的

      可是匿名类型太过匿名了,我们没办法用 `a这样的命名,也无法指定 这是很麻烦的

      在这种状况下 与其说我们需要一个匿名类型 不如说我们更需要定义一个类似Tuple的 轻量级类型。

      如果支持这样的语法 return View( new {a=1,b=2} *nameas * Type1)

      我们就可以大大方方在View<>中写上 View了。

      这样的功能通过修改编译器应该是可以做到的,也许有更好的定义实现访法。

    49. 鬼域马

      链接

      鬼域马 2011-10-10 09:19:36

      把老赵文章遍历一遍是个浩大的项目,看到我 内流满面

      说说想法,实践后,和大家分享其中的乐趣固然好,大没必要说服谁。 当然 心胸宽广 把博客当吵架 休闲 娱乐的好去处, 也没人能拦得住。

      ViewData["Title"] (asp.net mvc2.0) 和 ViewBag.Title (asp.net mvc3.0) 感觉用法上差不多,形式上嘛 嘿嘿。

      发觉到 Mono.Cecil 的修改IL的内容了

      但能修改什么, 怎么修改,那些是有意义的修改 有哪些副作用。这些内容好像是空白呀。

      这个可以有。但这个真没有。 :)

    50. bjbkp
      121.63.36.*

      链接

      bjbkp 2011-10-11 20:23:15

      老赵怎么好久不写文章了? 期待得很哪.....

    51. Eric Poon

      链接

      Eric Poon 2011-10-23 19:04:35

      测试了,很好用,不过想要在FormModel中添加一个数据库的列表,然后在View中输出时,没有智能提示,字段多起来还是需要来回查看属性名字。

    52. 阿斯旺福
      110.103.77.*

      链接

      阿斯旺福 2011-10-24 09:50:26

      挺有意思的方法. 不过楼主的想法真诡异. 为啥不直接ViewBag.Title = title

    53. 老赵
      admin

      链接

      老赵 2011-10-24 19:51:46

      @阿斯旺福

      那么你试试看:

      1 ViewBag.Product = new { Title = "Hello World" };

      怎么最基本的举一反三都做不到呢?

    54. 老赵
      admin

      链接

      老赵 2011-10-24 19:52:35

      @鬼域马

      听不懂你在说什么,我觉得很多东西都是非常明显的,不用多说,你觉得还需要说什么呢?

    55. StrongBird
      168.159.144.*

      链接

      StrongBird 2011-10-25 17:24:29

      mcpssx兄貌似完全没有搞懂WinRT是怎么回事,推出的根本目的是什么。 WinRT基础类库是用C++写的,这和.NET是否该被摒弃或绕开有任何关系?小弟不才,但实在看不下去这种没有仔细去了解一项技术就开始乱喷的行径啊……

    56. 阿斯旺福
      110.103.77.*

      链接

      阿斯旺福 2011-10-26 09:00:45

      @老赵: 怎么最基本的举一反三都做不到呢?

      这个怎么了?

    57. 老赵
      admin

      链接

      老赵 2011-11-05 22:15:23

      @阿斯旺福

      自己试试看不就知道咯?

    58. Leo

      链接

      Leo 2011-11-14 09:47:35

      这个方法对业务变动比较多的很有用。语言神马的都是浮云,简化写代码的过程才是王道。

    59. 老赵
      admin

      链接

      老赵 2011-11-14 11:54:25

      @Leo

      所以我追求的是写代码的爽快成都嘛,活活。

    60. szq
      27.115.98.*

      链接

      szq 2011-12-16 10:05:36

      mcpssx低级人物

    61. Gabriel Zhang

      链接

      Gabriel Zhang 2012-01-10 12:16:07

      老赵,你好!我想请教几个关于部署Linux服务器上时Nginx的需要做哪些配置的问题,比如安全性上面的,我现在测试都只是简单的配置程序能够跑起来,如果发布到线上环境,要做其他的哪些配置?谢谢

    62. pfcao

      链接

      pfcao 2012-05-02 16:10:33

      俺写了个Controller好像也实现了这个功能,需要的时候只要继承这个类就成了,而且在View里支持foreach等语句。班门弄斧,有什么不可取的请大侠们指点一下吧。

      01 public class DynamicModelController : Controller
      02 {
      03     protected override ViewResult View(string viewName, string masterName, object model)
      04     {
      05         return base.View(viewName, masterName, ObjectToDictionary(model));
      06     }
      07  
      08     private static object ObjectToDictionary(object model)
      09     {
      10         var modelType = model.GetType();
      11         if (model == null || modelType.IsVisible ) { return model; }
      12         var dmodel = new System.Dynamic.ExpandoObject();
      13         foreach (var propertyInfo in modelType.GetProperties())
      14         {
      15             object value = ObjectToDictionary( propertyInfo.GetValue(model, null));
      16             (dmodel as IDictionary<stringobject>) .Add(propertyInfo.Name, value);
      17         }
      18         return dmodel;
      19     }
      20 }
    63. 老赵
      admin

      链接

      老赵 2012-05-02 22:26:41

      @pfcao

      其实还有缺漏,比如某个属性是个集合,其中的元素就没处理……

    64. pfcao

      链接

      pfcao 2012-05-03 09:15:17

      恩,是的。若某个属性是个集合,那个集合里面的匿名类就不能访问了。只要是被公开类包裹起来的匿名类都不能访问,因为这些都没有转换过。看来这与您的方案还是不等价的了。谢谢指正。

    65. seasunk
      218.19.41.*

      链接

      seasunk 2012-07-10 11:34:59

      真的是非常棒的idea.這樣我基本可以不要VIEW層的MODEL了。而且更直慣,打算用到項目上; 不過在VIEW時是dynamic,相對強類型,應該會有那麼點性能損失,不過相對來說,利遠到於弊啊~~

    66. xiaoyekudingcha
      115.197.107.*

      链接

      xiaoyekudingcha 2012-08-22 09:49:57

      说下,灰色的内容显示方式能不能调整下,能在我选中的情况下看的不那么累。

    67. jinsikui
      218.205.161.*

      链接

      jinsikui 2013-12-05 11:48:51

      感觉这篇文章的标题应该是: “使用Mono.Cecil辅助ASP.NET MVC使用匿名类型Model” 因为dynamic的model可以绑定到任意public的类型,只有绑定到匿名类型时才会出现无法访问的情况呀

  • 相关阅读:
    Billing Invoice Split Rule
    From ProjectMagazine
    Link to PMP
    测试发现数据库性能问题后的SQL调优
    被jQuery折腾得半死,揭秘为何jQuery为何在IE/Firefox下均无法使用
    解决'将 expression 转换为数据类型 nvarchar 时出现算术溢出错误。'
    几年来ASP.NET官方站点首次改版,意味着MVC时代全面到来?
    Collection was modified; enumeration operation may not execute.的异常处理
    解决Sandcastle Help File Builder报错问题
    如何查看Windows服务所对应的端口?
  • 原文地址:https://www.cnblogs.com/grj001/p/12225254.html
Copyright © 2011-2022 走看看