我们的Web应用程序使用了一个自定义模板框架,其实现是用各种语言编写的,我正在调查是否可以使用Razor View引擎在ASP.NET MVC应用程序中使用它。我们已经有一个使用Web窗体视图引擎的实现,但我也希望能够使用Razor。
模板在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 :(得分: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)
解决方案草案
我想创建自己的渲染引擎,它将执行以下操作:
<强>研究强>
我找到了以下资源:
最终解决方案
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
。
请告诉我它是否对您有所帮助。您也可以分享您的解决方案。