2012-10-30 58 views
2

我們有一個自定義的模板框架,我們的Web應用程序使用各種語言編寫的實現,我正在研究是否可以在ASP中使用它。使用Razor View引擎的NET MVC應用程序。我們已經有了一個使用Web窗體視圖引擎的實現,但我也渴望能夠使用Razor。將Razor View Engine與自定義模板框架結合使用

該模板在一個html文件中定義,該文件包含在運行時用適用的html解釋和替換的宏標籤。以下是該文件的一個高度簡化的版本: -

[doctype] 
<html> 
    <head> 
    [HeadScript] 
    [HeadSectionText] 
    </head> 
    <body id="[if Home][Home][else]body[end if]"> 
    [form] 
     [Content] 
    [end form] 
    [EndBodyScript] 
    </body> 
</html> 

正如你所看到的,有注入到HTML文件的各個部分,與一些本由一個簡單的條件邏輯執行處理的機會。爲了在Razor中使用它,我需要能夠處理模板中的所有宏標記,包括從正在渲染的Razor視圖中插入HTML,並將此操作的輸出作爲HTML最終發送給客戶。

當談到MVC開發時,我很綠,但我知道我可以創建一個自定義的ViewEngine和IView實現。也許我可以使用它來實現我想要的,使用RazorView類的自定義引擎將實際內容插入到我們的模板中。這聽起來像一個可行的解決方案?如果是這樣,有沒有人有任何提示讓我開始?

目前我有一個kludgy解決方案,我使用ASP.NET WebForms引擎並呈現部分Razor視圖,但長期以來我寧願有一個解決方案,可以將WebForms引擎完全排除在等式之外。

任何推在正確的方向非常讚賞。

+0

好問題。其實我有非常類似的問題。有關這方面的消息嗎? –

+0

我從來沒有找到一個理想的解決方案,所以我使用ASPX視圖引擎的頁面只包含部分剃刀視圖。不漂亮,但它的作品。而且我仍然使用剃刀爲我的大多數標記 – Cleggy

回答

1

我設法弄清楚了一些事情。雖然我的問題並不完全一樣,但它確實可以幫助你。但首先是事情。

問題

我有很多的控制(在我的情況下,他們是局部視圖)。例如:

Views/Shared/EditName.cshtml 
Views/Shared/EditAddress.cshtml 
Views/Shared/EditEmail.cshtml 
Views/Shared/EditFavoriteColour.cshtml 

我想定義這些控件的組(在數據庫或web.config中),例如:

SimpleEditGroup: 
    EditName 
ExtendedEditGroup: 
    EditName 
    EditEmail 
FullEditGroup: 
    EditName 
    EditAddress 
    EditEmail 
    EditFavoriteColour 

然後我想渲染基於特定組的圖。我在想以下語法就​​足夠了。

@Html.Partial("ControlGroup:ExtendedEditGroup", Model) 

草案解決方案的

我想創建自己的渲染引擎,這將做到以下幾點:

  1. 如果視圖名稱開頭「ControlGroup:」那使用以前定義的組來呈現頁面。每個控件都應該由RazorViewEngine渲染。
  2. 如果視圖的名稱不是以「ControlGroup:」開頭,那就讓RazorViewEngine完成它的工作。

研究

我發現以下資源:

  1. 文章在CodeProject - Custom ViewEngine in ASP.NET MVC3
  2. 基於StackOverflow的問題文章 - Creating a Widget system in ASP.NET MVC 3
  3. 我建議你這本書Pro ASP.NET MVC 3 Framework 。它會給你一個想法,你可以在ASP.NET MVC 3中自定義多少東西。
  4. 當然源代碼ASP.NET MVC 3 RTM是非常有用的。

最終解決

MyViewEngine:

public class MyViewEngine : RazorViewEngine 
{ 
    IDictionary<string, List<string>> groups = new Dictionary<string, List<string>>(); 

    public MyViewEngine() 
    { 
    // Temporary data source 
    groups["SimpleEditGroup"] = new List<string>() { "EditName"}; 
    groups["ExtendedEditGroup"] = new List<string>() { "EditName", "EditEmail"}; 
    } 

    public override ViewEngineResult FindView(ControllerContext controllerContext, 
      string viewName, string masterName, bool useCache) 
    { 
    if (viewName.StartsWith("ControlGroup")) 
    { 
     var groupName = viewName.Split(':')[1]; 
     var controls = new List<ViewEngineResult>(); 

     foreach (var controlName in groups[groupName]) 
     { 
     // Find each control using Razor magic 
     var control = base.FindPartialView(controllerContext, controlName, useCache); 
     if (control.View != null) 
     { 
      controls.Add(control); 
     } 
     } 

     if(controls.Count > 0) 
     return new ViewEngineResult(new MyView(controls), this); 
    } 

    return base.FindView(controllerContext, viewName, masterName, useCache); 
    } 
} 

MyView.cs:

public class MyView : IView 
{ 
    IList<ViewEngineResult> controls; 

    public MyView(IList<ViewEngineResult> _controls) 
    { 
    controls = _controls; 
    } 

    public void Render(ViewContext viewContext, TextWriter textWriter) 
    { 
    // For simplicity I used table for layout 
    textWriter.Write("<table border='1'>"); 

    foreach (var ctrl in controls) 
    { 
     textWriter.Write("<tr><td>"); 

     // Render control using Razor 
     ctrl.View.Render(viewContext, textWriter); 

     textWriter.Write("</td></tr>"); 
    } 

    textWriter.Write("</table>"); 
    } 
} 

不要忘記在Global.asax中ViewEngines.Engines.Add(new MyViewEngine());

註冊您的新引擎

團圓結局

我可以以兩種方式使用:使用Render.Partial或從我的控制器只返回PartialView嵌入視圖。

讓我知道它是否對你有幫助。而且你也可以分享你的解決方案。

+0

這一切看起來很有希望。實際上,我現在已經進入了另一個(非MVC)項目,但會嘗試使用您發佈的信息找到重新訪問該項目的時間。 – Cleggy

相關問題