Make ASP.NET MVC 3 Razor View Engine ignore .vbhtm

2019-02-01 01:52发布

How can I remove the VB Razor Engine or configure the RazorViewEngine to not use and look for .vbhtml files on disk? For new ASP.NET MVC 3 Razor projects, I always remove the WebFormViewEngine in Application_Start because I won't ever be using it and so I don't need it to search for .aspx, .ascx or .master files on disk. For this same reason I would like to avoid .vbhtml file searching.

7条回答
走好不送
2楼-- · 2019-02-01 02:20

This one keeps the original RazorViewEngine and cleans away the VB extensions.

//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));
查看更多
来,给爷笑一个
3楼-- · 2019-02-01 02:22

I figured I'd merge the examples from @tugberk and @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楼-- · 2019-02-01 02:25

This is the code for your custom view engine:

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" };
    }
}

Register this on Application_Start method like this:

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CSRazorViewEngine());
查看更多
时光不老,我们不散
5楼-- · 2019-02-01 02:27

Like @Alex, combining and extending previous solutions.

Just in case you want to specify extensions for other ViewEngines, inherit from the 'original' and either build or filter (your preference, I just thought filtering seemed more work than starting a fresh list).

Usage:

// 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"));

Engine-specific:

/// <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

Which uses:

/// <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楼-- · 2019-02-01 02:31

There is no point in doing this.

However, if you really want to, you can clear ViewEngines, then register your own RazorViewEngine with FileExtensions set to ".cshtml".

查看更多
The star\"
7楼-- · 2019-02-01 02:33

A summary from above with a single class.

Use it like this:

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

Class:

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();
    }
}
查看更多
登录 后发表回答