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

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

  • /Themes/Default/Views/{область}/{контроллер}/{действие}.cshtml
  • /Modules/{область}/Views/{контроллер}/{действие}.cshtml

Я был бы очень признателен, если бы кто-то мог помочь.

Спасибо


person nfplee    schedule 16.06.2011    source источник


Ответы (3)


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

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

person Rob West    schedule 16.06.2011
comment
Привет, спасибо, я разместил код, который использовал, если он кому-нибудь поможет. - person nfplee; 16.06.2011

Вот код, если кому интересно:

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());

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

person nfplee    schedule 16.06.2011

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

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

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

person 3Dave    schedule 16.06.2011
comment
Спасибо, я буду иметь это в виду, если производительность станет проблемой. - person nfplee; 16.06.2011