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的类型,只有绑定到匿名类型时才会出现无法访问的情况呀

  • 相关阅读:
    Eclipse 导入项目乱码问题(中文乱码)
    sql中视图视图的作用
    Java基础-super关键字与this关键字
    Android LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)的参数理解
    Android View和ViewGroup
    工厂方法模式(java 设计模式)
    设计模式(java) 单例模式 单例类
    eclipse乱码解决方法
    No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案
    【转】使用 Eclipse 调试 Java 程序的 10 个技巧
  • 原文地址:https://www.cnblogs.com/grj001/p/12225254.html
Copyright © 2011-2022 走看看