Переопределите стандартный ViewEngine для просмотра в разных каталогах

Я создал область в Visual Studio, которая автоматически добавляет соответствующие биты в каталог "Области". Я переименовал это в "Модули", но теперь, когда я перехожу к / {area} / {controller / {action}, он по-прежнему ищет представление в каталоге /Areas/{area}/Views/{controller/{action}, а не каталог /Modules/{area}/Views/{controller/{action}. Я также хотел бы иметь возможность переопределить представление для определенных тем. Поэтому мне было интересно, как я могу настроить механизм представления по умолчанию, чтобы искать представление в следующих местах:

  • /Themes/Default/Views/{area}/{controller}/{action}.cshtml
  • /Modules/{area}/Views/{controller}/{action}.cshtml

Буду очень признателен, если кто-нибудь сможет помочь.

Спасибо

3 ответа

Решение

Поскольку исходный код ASP.NET MVC доступен, на эти вопросы легко ответить, посмотрев на источник. Если вы посмотрите на класс WebFormViewEngine, вы увидите перечисленные местоположения, и вам будет легко унаследовать их и настроить их.

Однако отказ от использования кода в соответствии с соглашением просто усложнит вашу жизнь, поэтому я бы посоветовал жить с местами по умолчанию.

Вот код, если кто-то заинтересован:

public class CustomRazorViewEngine : RazorViewEngine {
    public CustomRazorViewEngine()
        : this(null) {
    }

    public CustomRazorViewEngine(IViewPageActivator viewPageActivator)
        : base(viewPageActivator) {
        AreaViewLocationFormats = new[] {
            "~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
            "~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
            "~/Modules/{2}/Views/{1}/{0}.cshtml",
            "~/Modules/{2}/Views/Shared/{0}.cshtml"
        };
        AreaMasterLocationFormats = new[] {
            "~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
            "~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
            "~/Modules/{2}/Views/{1}/{0}.cshtml",
            "~/Modules/{2}/Views/Shared/{0}.cshtml"
        };
        AreaPartialViewLocationFormats = new[] {
            "~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
            "~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
            "~/Modules/{2}/Views/{1}/{0}.cshtml",
            "~/Modules/{2}/Views/Shared/{0}.cshtml"
        };
    }
}

Теперь просто поместите следующее в событие Application_Start в файле Global.asax.cs:

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

Надеюсь это поможет.

Код, который вы разместили, очень похож на то, что я делал несколько месяцев назад.

У меня также есть шаг предварительной обработки (запускаемый по требованию или во время компиляции), который находит все файлы.cshtml в иерархии папок сайта и добавляет их относительные пути к таблице в базе данных. Сайт кэширует эти данные при запуске. Затем пользовательский механизм просмотра выполняет поиск в этом списке и проверяет диск только при обнаружении совпадения.

Это работает очень, очень хорошо. Отказ от доступа к диску, вероятно, поможет, только если вы работаете с очень загруженным сайтом. Несмотря на то, что доступ к диску очень медленный, обычно это не является узким местом в производительности, и ASP.NET выполняет собственное интеллектуальное кэширование.

Другие вопросы по тегам