使ASP.NET MVC 3 Razor View Engine忽略.vbhtml文件

时间:2011-05-18 18:35:51

标签: asp.net-mvc asp.net-mvc-3 razor

如何删除VB Razor Engine或将RazorViewEngine配置为不使用并在磁盘上查找.vbhtml文件?对于新的ASP.NET MVC 3 Razor项目,我总是删除Application_Start中的WebFormViewEngine,因为我永远不会使用它,因此我不需要它来搜索磁盘上的.aspx,.ascx或.master文件。出于同样的原因,我想避免.vbhtml文件搜索。

7 个答案:

答案 0 :(得分:12)

这是您的自定义视图引擎的代码:

public class CSRazorViewEngine : RazorViewEngine {

    public CSRazorViewEngine() {

        base.AreaViewLocationFormats = new string[] { 
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.cshtml"
        };

        base.AreaMasterLocationFormats = new string[] { 
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.cshtml"
        };

        base.AreaPartialViewLocationFormats = new string[] { 
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.cshtml"
        };

        base.ViewLocationFormats = new string[] {
            "~/Views/{1}/{0}.cshtml",
            "~/Views/Shared/{0}.cshtml"
        };

        base.PartialViewLocationFormats = new string[] {
            "~/Views/{1}/{0}.cshtml",
            "~/Views/Shared/{0}.cshtml"
        };

        base.MasterLocationFormats = new string[] {
            "~/Views/{1}/{0}.cshtml",
            "~/Views/Shared/{0}.cshtml"
        };

        base.FileExtensions = new string[] { "cshtml" };
    }
}

在Application_Start方法上注册,如下所示:

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CSRazorViewEngine());

答案 1 :(得分:11)

如果我永远不会使用它,为什么删除.vbhtml中的搜索没有意义?

我是这样做的(但我仍然不知道删除vbhtml是一件好事):

protected void Application_Start()
{
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new RazorViewEngine().DisableVbhtml());

    ...
}

扩展方法代码:

public static RazorViewEngine DisableVbhtml(this RazorViewEngine engine)
{
    engine.AreaViewLocationFormats = FilterOutVbhtml(engine.AreaViewLocationFormats);
    engine.AreaMasterLocationFormats = FilterOutVbhtml(engine.AreaMasterLocationFormats);
    engine.AreaPartialViewLocationFormats = FilterOutVbhtml(engine.AreaPartialViewLocationFormats);
    engine.ViewLocationFormats = FilterOutVbhtml(engine.ViewLocationFormats);
    engine.MasterLocationFormats = FilterOutVbhtml(engine.MasterLocationFormats);
    engine.PartialViewLocationFormats = FilterOutVbhtml(engine.PartialViewLocationFormats);
    engine.FileExtensions = FilterOutVbhtml(engine.FileExtensions);

    return engine;
}

private static string[] FilterOutVbhtml(string[] source)
{
    return source.Where(s => !s.Contains("vbhtml")).ToArray();
}

答案 2 :(得分:8)

这样做没有意义。

但是,如果您真的想要,可以清除ViewEngines,然后在RazorViewEngine设置为FileExtensions的情况下注册您自己的".cshtml"

答案 3 :(得分:7)

我想我会合并@tugberk和@Dimps的例子:

public class CSHtmlRazorViewEngine : RazorViewEngine {
    public CSHtmlRazorViewEngine()
        : base() {
        this.AreaMasterLocationFormats = Filter(base.AreaMasterLocationFormats);
        this.AreaPartialViewLocationFormats = Filter(base.AreaPartialViewLocationFormats);
        this.AreaViewLocationFormats = Filter(base.AreaViewLocationFormats);
        this.FileExtensions = Filter(base.FileExtensions);
        this.MasterLocationFormats = Filter(base.MasterLocationFormats);
        this.PartialViewLocationFormats = Filter(base.PartialViewLocationFormats);
        this.ViewLocationFormats = Filter(base.ViewLocationFormats);
    }

    private static string[] Filter(
        string[] source) {
        return source.Where(
            s =>
                s.Contains("cshtml")).ToArray();
    }
}

答案 4 :(得分:3)

上面的摘要,单个班级。

像这样使用:

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new FilteredRazorViewEngine("cshtml"));

类别:

public class FilteredRazorViewEngine : RazorViewEngine
{
    private string _extension;

    public FilteredRazorViewEngine(string viewTypeExtension)
        : base()
    {
        _extension = viewTypeExtension;

        AreaMasterLocationFormats = Filter(base.AreaMasterLocationFormats);
        AreaPartialViewLocationFormats = Filter(base.AreaPartialViewLocationFormats);
        AreaViewLocationFormats = Filter(base.AreaViewLocationFormats);
        FileExtensions = Filter(base.FileExtensions);
        MasterLocationFormats = Filter(base.MasterLocationFormats);
        PartialViewLocationFormats = Filter(base.PartialViewLocationFormats);
        ViewLocationFormats = Filter(base.ViewLocationFormats);
    }

    private string[] Filter(string[] source)
    {
        return source.Where(
            s =>
                s.Contains(_extension)).ToArray();
    }
}

答案 5 :(得分:1)

@Alex类似,合并并扩展以前的解决方案。

如果您想为其他ViewEngines指定扩展名,请继承“原始”并构建或过滤(您的偏好,我只是认为过滤似乎比开始一个新列表更有用)。

用法:

// custom extension(s)
ViewEngines.Engines.UseOnly(new ExtensionSpecificRazorViewEngine("cshtml"));
ViewEngines.Engines.UseOnly(new ExtensionSpecificRazorViewEngine("myhtml", "xhtml"));

// filtered from original extensions
ViewEngines.Engines.UseOnly(new ExtensionSpecificRazorViewEngine(false, "cshtml", "vbhtml"));

引擎特异性:

/// <summary>
/// Razor View Engine only expecting the specified extensions
/// </summary>
public class ExtensionSpecificRazorViewEngine : RazorViewEngine
{
    public ExtensionSpecificRazorViewEngine(params string[] extensions) : this(true, extensions) { }

    public ExtensionSpecificRazorViewEngine(bool isBuildOrFilter, params string[] extensions) : this(null, isBuildOrFilter, extensions) {}

    /// <summary>
    /// Create a new ViewEngine only expecting the provided extension
    /// </summary>
    /// <param name="viewPageActivator"></param>
    /// <param name="isBuildOrFilter"></param>
    /// <param name="extensions"></param>
    public ExtensionSpecificRazorViewEngine(IViewPageActivator viewPageActivator, bool isBuildOrFilter, params string[] extensions)
        : base(viewPageActivator)
    {
        if (isBuildOrFilter) this.BuildSpecifically(extensions);
        else this.FilterSpecifically(extensions);

        this.FileExtensions = extensions;
    }
}//---  class   ExtensionSpecificRazorViewEngine

使用:

/// <summary>
/// Because classes can't inherit from multiple classes, we put the build/filter logic in a helper
/// that's used by the ViewEngine implementation which inherits from RazorViewEngine or WebFormViewEngine, etc
/// </summary>
public static class ExtensionSpecificViewEngineExtensions
{
    /// <summary>
    /// <para>Given a collection of ViewEngines, clear them and add the indicated engine</para>
    /// <example>ex) <code>ViewEngines.Engines.UseOnly(new RazorViewEngine());</code></example>
    /// </summary>
    /// <param name="engines">list of available engines</param>
    /// <param name="engine">the only engine to use</param>
    public static void UseOnly(this ViewEngineCollection engines, IViewEngine engine)
    {
        engines.Clear();
        engines.Add(engine);
    }

    /// <summary>
    /// Build the lookup paths specifically for the indicated extension(s)
    /// </summary>
    /// <param name="engine"></param>
    /// <param name="extensions"></param>
    public static void BuildSpecifically(this BuildManagerViewEngine engine, string[] extensions)
    {
        engine.AreaMasterLocationFormats =      Build(extensions, "~/Areas/{2}");
        engine.AreaPartialViewLocationFormats = Build(extensions, "~/Areas/{2}");
        engine.AreaViewLocationFormats =        Build(extensions, "~/Areas/{2}");
        engine.FileExtensions =                 Build(extensions);
        engine.MasterLocationFormats =          Build(extensions);
        engine.PartialViewLocationFormats =     Build(extensions);
        engine.ViewLocationFormats =            Build(extensions);
    }
    /// <summary>
    /// Filter the existing, default extensions from the view engine's lookup paths for the indicated extensions
    /// </summary>
    /// <param name="engine"></param>
    /// <param name="extensions"></param>
    public static void FilterSpecifically(this BuildManagerViewEngine engine, string[] extensions)
    {
        engine.AreaMasterLocationFormats =      Filter(extensions, engine/*base*/.AreaMasterLocationFormats);
        engine.AreaPartialViewLocationFormats = Filter(extensions, engine/*base*/.AreaPartialViewLocationFormats);
        engine.AreaViewLocationFormats =        Filter(extensions, engine/*base*/.AreaViewLocationFormats);
        engine.FileExtensions =                 Filter(extensions, engine/*base*/.FileExtensions);
        engine.MasterLocationFormats =          Filter(extensions, engine/*base*/.MasterLocationFormats);
        engine.PartialViewLocationFormats =     Filter(extensions, engine/*base*/.PartialViewLocationFormats);
        engine.ViewLocationFormats =            Filter(extensions, engine/*base*/.ViewLocationFormats);
    }

    private static string[] Build(string[] extensions, string prefix = "~")
    {
        return extensions.SelectMany(x => new[] {
                prefix + "/Views/{1}/{0}." + x,
                prefix + "/Views/Shared/{0}." + x
            }).ToArray();
    }

    private static string[] Filter(string[] extensions, params string[] source)
    {
        return source.Where(s => extensions.Any(s.EndsWith)).ToArray();
    }
}//---  class   ExtensionSpecificViewEngineExtensions

答案 6 :(得分:1)

这个保留原始RazorViewEngine并清除VB扩展名。

//Remove the legacy ASPX view engine
ViewEngines.Engines.Remove(ViewEngines.Engines.OfType<WebFormViewEngine>().Single());

//Remove VB from the remaining view engine
var target = ViewEngines.Engines.OfType<RazorViewEngine>().Single();
(new Expression<Func<RazorViewEngine,string[]>>[] {
    y => y.FileExtensions,
    y => y.ViewLocationFormats,
    y => y.PartialViewLocationFormats,
    y => y.MasterLocationFormats,
    y => y.AreaMasterLocationFormats,
    y => y.AreaPartialViewLocationFormats,
    y => y.AreaViewLocationFormats
}
).Select(y => (PropertyInfo)((MemberExpression)y.Body).Member).ToList()
    .ForEach(y => y.SetValue(target,((string[])y.GetValue(target))
    .Where(x => x.EndsWith("cshtml")).ToArray(),null));