2013-05-02 72 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