MVC4 Razor自定义视图定位器

Joe*_*ele 3 razor asp.net-mvc-4

我正在开发一个旨在为两个域提供服务的MVC4应用程序.我们的大多数内容将在域之间共享,但有时我们需要根据请求来自哪个站点呈现不同的标记(使用Razor).

理想情况下,我想要一个基于约定的方法,允许我有这样的文件夹结构:

Views
+ Domain1
    + ControllerName
        View1
        View2
+ Domain2
    + ControllerName
        View1
+ ControllerName
   View1
   View2
Run Code Online (Sandbox Code Playgroud)

在解析视图时,我想首先检查特定于域的文件夹,然后检查常规视图文件夹.

我的第一个想法是实现一个继承RazorViewEngine的自定义视图引擎,它将根据请求域交换ViewLocationFormats字符串.不幸的是,所有这些东西都埋没在VirtualPathProviderEngine中,无法覆盖.

Joe*_*ele 9

事实证明,答案是为每个了解域特定文件夹的域创建一个自定义视图引擎(继承自RazorViewEngine):

public class Domain1ViewEngine() : RazorViewEngine
{
        ...

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

        ...
}
Run Code Online (Sandbox Code Playgroud)

然后我需要覆盖FindViewFindPartialView方法,以便它只是在请求来自正确的域时才尝试查找定位视图:

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
    if ([THIS IS NOT THE RIGHT DOMAIN]) 
    {
        return new ViewEngineResult(new string[] { });
    }

    return base.FindView(controllerContext, viewName, masterName, useCache);
}
Run Code Online (Sandbox Code Playgroud)

为了完成这个过程,我Global.asax.cs以通常的方式注册了视图引擎:

protected void Application_Start()
{
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new Domain1ViewEngine());
    ViewEngines.Engines.Add(new RazorViewEngine());
}
Run Code Online (Sandbox Code Playgroud)