2013-05-02 71 views
5

我正在编写一个HtmlHelper扩展,我需要按名称搜索模板的存在。所讨论的模板可能是显示或编辑模板,具体取决于上下文。我最初的想法是使用ViewEngines.Engines.FindPartialView方法。但是,看起来这种方法没有搜索~/Views/Shared/DisplayTemplates~/Views/Shared/EditorTemplates目录。
我想这是有原因的。毕竟,ViewEngine怎么知道是否返回显示或编辑器模板没有一些额外的上下文信息?按名称查找MVC模板查看

所以,这导致了一个问题:我如何可以搜索特定的EditorTemplate/DisplayTemplate我已经考虑添加自定义视图引擎的ViewEngines收集到包括这些位置。然而,我担心这可能是有问题的。

我最关心的是,DisplayTemplate/EditorTemplate视图可能担任了的东西意外。还有人认为这是一个问题吗?
在必要时新增特定的DisplayTemplateViewEngine/EditorTemplateViewEngine实例并保持ViewEngines集合不含此特定功能是否更好?
还有什么我失踪?

回答

4

我绝对喜欢的MVC框架是开放的资源!我能够从TemplateHelpers类(MVC运行时的内部)确定在渲染模板时考虑DataBoundControlMode。答案很简单!我所要做的就是将模板名称加上适当的模板导演。因此,要找到显示模板:

var metadata = ModelMetadata.FromLambdaExpression(expression, HtmlHelper.ViewData); 
ViewEngines.Engines.FindPartialView(
    _controllerContext, 
    string.Format("DisplayTemplates/{0}", metadata.TemplateHint)) 

不需要额外的视图引擎或路由!如果您对应用程序感兴趣,我的帮助程序会为给定模型自动生成UI组件。我想让自定义模板的存在绕过自动渲染。

+0

这就是答案。不过,我不能在几天之内标记它。对不起,如果你被这篇文章吸引,因为它显然是'未答复'的状态。 – 2013-05-02 15:11:10

+0

什么是metadata.TemplateHint或它来自哪里? – xr280xr 2015-07-20 21:48:39

+1

@ xr280xr:已更新为包含元数据定义。希望为您服务! – 2015-07-27 22:43:50

0

A WebFormViewEngine有几个属性定义(模式)位置来搜索视图。

您可以按照您使用的视图引擎的惯例,或者使用自定义视图路径创建自定义视图引擎(用于examlpe扩展Razor)。

后者解释here

public class CustomViewEngine : RazorViewEngine 
{ 
    public CustomViewEngine() 
    { 
     var viewLocations = new[] { 
      "~/Views/{1}/{0}.cshtml", 
      "~/Views/Shared/{0}.cshtml", 
      "~/Views/Shared/DisplayTemplates/{0}.cshtml", 
      "~/Views/Shared/DisplayTemplates/{1}/{0}.cshtml", 
      // etc 
     }; 

     this.PartialViewLocationFormats = viewLocations; 
     this.ViewLocationFormats = viewLocations; 
    } 
} 

所以我想在你的帮助,你应该查找当前视图引擎,并期待其观点,位置路径,为了搜索。 Html帮助程序是否有获取当前正在运行的视图的方法或属性?

+0

感谢您的回复。我实际上并没有打破惯例;我的结构正在满足预期的MVC体系结构定义。问题是ViewEnginesCollection的FindPartialView方法不搜索这些位置,因为它不知道您是否想要显示或编辑器版本。不过,我确实找到了解决方案。请参阅我的答案以供参考。再次感谢。 – 2013-05-02 14:57:07

+0

1)您示例中的代码是默认的Razor行为吗? 2)“{0}”和“{1}”指的是什么? – Shimmy 2015-04-09 09:06:02

+0

@Shimmy [这是默认](https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/RazorViewEngine.cs)。替换值为{0}'=视图名称,'{1}'=控制器名称和'{2}'=区域名称(参见本文件底部的['ViewLocation'和'AreaAwareViewLocation'] //github.com/ASP-NET-MVC/aspnetwebstack/blob/4e40cdef9c8a8226685f95ef03b746bc8322aa92/src/System.Web.Mvc/VirtualPathProviderViewEngine.cs))。 – CodeCaster 2015-04-09 09:07:42

0

为什么你刚才绘制的相对路径

string path = Server.MapPath("~/View/"); 

然后检查是否在特定目录上.cshtml退出的文件出口基地

string fileName = "MyView.cshtml"; 
if (File.Exists(path + fileName)) 
    //do somethings 
else 
    //do another things 
+0

使用ViewEngine的一个好处是它可以被模拟使其可测试。这个解决方案真的很难进行单元测试。尽管您的意见很高兴! – 2013-05-02 15:09:38