MVC3自定义视图引擎

本文关键字:引擎 视图 自定义 MVC3 | 更新日期: 2023-09-27 18:14:41

我有一个来自WebFormViewEngine的自定义视图引擎。这里有很多东西,主要是缓存。我想能够使用WebFormViewEngine和RazorViewEngine在同一时间,这是可能的吗?理想情况下,我想做;

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

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

编辑:我应该把我的问题写得更好。由于我的自定义视图引擎派生自WebFormViewEngine,它显然使用WebForms,我不能派生自两个类。我可以从RazorViewEngine派生,但我将失去WebForms。我可以完全复制我的代码,从RazorViewEngine派生并编辑视图文件扩展名等,但正如我所说,我在视图引擎中有很多自定义代码,并且将复制数百行。

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

MVC3自定义视图引擎

这是可能的,但不建议采用方式,因为这会给您的项目带来一些混乱。你可以阅读关于它的好文章:使用多个视图引擎

这不重要

默认情况下,MVC3包含WebFormsViewEngineRazorViewEngine,这两个都是自动注册的。我相信它们被订购为WebFormsViewEngine,然后RazorViewEngine也,这意味着web表单视图将首先被检查。如果它找到一个视图,它将使用它。如果不能,它将使用下一个视图引擎,也就是Razor视图引擎。

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

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

然后,我创建了另一个类,从MyViewEngine派生为WebForms:

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/。将WebFormView改为RazorView。将它们添加到ViewEngine集合:

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

,现在它们又完美地工作了,与我所有的自定义缓存逻辑并排。