在重复的动态类型的部分视图

时间:2015-07-09 00:57:00

标签: asp.net-mvc-4 razor anonymous-types asp.net-mvc-partialview razorengine

我将匿名类型作为@model的一部分传递到动态部分视图中,其中一个属性是包含一些HTML的字符串。当我使用HtmlHelper方法呈现属性时,Razor引擎会对字符串进行编码,从而在页面上生成文字文本 - 在这种情况下为<i>text</i>,而不是所需的 {{1 }}

由于它是一个动态类型的视图,我无法直接调用该属性。具体来说,如果我尝试绑定到text,我会得到@Model.MyField

RuntimeBindingException

理想情况下,我可以创建一个类型(或至少是一个接口)来为视图指定(我建议将其作为最佳解决方案),但我的工作范围不允许这样做。另外,我首先使用'object' does not contain a definition for 'MyField' ,这样我就可以为不同类型的模板进行回收,这些类型具有相同的属性名称,但这些属性的类型不同(yay遗留代码!)。 / p>

我已经查看了几个解决类似问题的相关问题,但答案对我的具体情况不起作用(由于需要将匿名类型传递给我的Partial View视图))。

尝试解决方案

  1. 好的,所以我假设我只是将我的IHtmlString属性换成其中一个String属性... nope。由于我有匿名类型,因此Razor引擎不知道IHtmlStringMyField,并且(我假设)调用IHtmlString,然后照常编码。

  2. 好吧,也许.ToString()更聪明?是的,但拒绝访问:

      

    &#39; System.Web.Mvc.HtmlHelper&#39;没有适用的方法名称&#39; DisplayFor&#39;但似乎有一个名称的扩展方法。无法动态分派扩展方法。考虑转换动态参数或调用扩展方法而不使用扩展方法语法。

    哦,对。动态调度 - 我无法通过匿名方法调用扩展方法,因为Razor不知道它们是什么。因为我使用@Html.DisplayFor明确告诉它,Jedi风格,&#34; 您不需要查看其身份&#34;。如果我总是知道它是什么类型,那么是的,我可以在不使用语法的情况下转换对象或调用扩展方法 - 但同样,@model dynamicdynamic。这里有鸡肉和鸡蛋的问题。

1 个答案:

答案 0 :(得分:0)

我发现/编译了两个解决方案,我都不满意。 YMMV:

  1. 在呈现每个ViewBag.MyField之前在父View中设置Partial View

    好吧,我应该早点想出这个,但必须提醒这种可能性here,因为我很少使用它(尽可能选择强类型视图)。我实际上早就尝试过这个,但由于我多次渲染Partial的方式,它似乎不合适。我实际上仍然不喜欢它,因为在父视图中,我必须在每次调用ViewBag.MyField之前不断更新@Html.Partial(对于我的用例来说是6次)。这使得C#代码变量重用在我的内容中间的页面中,很容易错过并且难以维护。

  2. 使用反射:object myField = ((Type)Model.GetType()).GetProperty("MyField").GetValue(Model);

    这最终是我决定使用的用例。即使反射wasn't intended for this scenario,即使它需要一些额外的错误检查。将要维护它的人比.NET MVC更熟悉反射,它将代码整合到一个位置 - 在它重要的页面上,并在顶部与其他“服务器端”操作。没有重复的电话或搜索引用。

    我实际上并不完全清楚它为什么会起作用(也适用于dynamic而不是object),但我假设它与Razor引擎有关,正在检查{ {1}}对象类型直接用于特定呈现已知类型(myField),而不是查看未知IHtmlString并且需要访问编译时不知道存在的属性。