MVC3自定义视图引擎

时间:2011-11-16 09:59:59

标签: c# asp.net-mvc-3 razor webforms

我有一个源自WebFormViewEngine的自定义View Engine。这里有很多东西,主要是缓存。我希望能够同时使用WebFormViewEngine和RazorViewEngine,这可能吗?理想情况下我想做;

ViewEngines.Add(new MyViewEngine<WebFormsViewEngine>()); ViewEngines.Add(new MyViewEngine<RazorViewEngine>());

如果存在.ascx / .aspx / .master文件则使用WebForms,否则使用Razor是一个.cshtml文件存在。

编辑:我应该更好地提出我的问题。由于我的自定义视图引擎派生自WebFormViewEngine,它显然使用WebForms,我无法从两个类派生。我可以从RazorViewEngine派生,但后来我将松散WebForms。我可以完全复制我的代码,派生自RazorViewEngine并编辑视图文件扩展名等,但正如我所说,我的视图引擎中有很多自定义代码,并且会复制数百行。

WebFormViewEngine和RazorViewEngine派生自BuildManagerViewEngine,后者又实现了IViewEngine。问题是我必须实现方法CreatePartialView()和CreateView()但我怎么知道使用泛型返回什么(WebForms / Razor?)?

3 个答案:

答案 0 :(得分:2)

可能,但不推荐方式,因为它会给您的项目带来一些混乱。你可以在上面阅读好文章:Using Multiple View Engines

答案 1 :(得分:1)

没关系。

默认情况下,MVC3同时包含WebFormsViewEngineRazorViewEngine,这些都是自动注册的。我相信它们的排序方式为WebFormsViewEngine,然后RazorViewEngine,这意味着将首先检查网络表单视图。如果找到视图,它将使用它。如果不能,它将使用下一个视图引擎,即Razor视图引擎。

您是否尝试删除自定义视图引擎并保留默认配置?

答案 2 :(得分:1)

最后,我最终创建了一个抽象类:public abstract class MyViewEngine : BuildManagerViewEngine, IViewEngine { },然后实现/覆盖FindViewFindPartialView方法(其中包含我的缓存代码)。我有一个在public abstract void SetSearchPaths();中调用的抽象方法ctor

然后我创建了另一个专门为WebForms派生MyViewEngine的类:

public class MyViewEngineWebForms : MyViewEngine
{
    public override void SetSearchPaths()
    {
        base.MasterLocationFormats = new string[] { "~/Skins/{2}/Views/{1}/{0}.master", "~/Skins/{2}/Views/Shared/{0}.master" };
        base.ViewLocationFormats = new string[] { "~/Skins/{2}/Views/{1}/{0}.aspx", "~/Skins/{2}/Views/Shared/{0}.aspx", "~/Skins/Shared/Views/{0}.aspx" };
        base.PartialViewLocationFormats = new string[] { "~/Skins/{2}/Views/{1}/{0}.ascx", "~/Skins/{2}/Views/Shared/{0}.ascx", "~/Skins/Shared/PartialViews/{0}.ascx" };
        base.FileExtensions = new string[] { "aspx", "ascx", "master" };
    }

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        return new WebFormView(controllerContext, partialPath, null, base.ViewPageActivator);
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        return new WebFormView(controllerContext, viewPath, masterPath, base.ViewPageActivator);
    }
}

并为Razor做了同样的事情,但将文件扩展名更改为.cshtml / .vbhtml并将WebFormView更改为RazorView。将它们添加到ViewEngine集合:

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new SeeTicketsWebFormsViewEngine());
ViewEngines.Engines.Add(new SeeTicketsRazorViewEngine());

现在它们再次完美地与我的所有自定义缓存逻辑并排运行。