У нас есть требование предоставить возможности создания скинов для приложения ASP.NET MVC3.
До сих пор мой подход заключался в том, чтобы решить эту проблему с помощью файла cookie и дочерних действий для файлов css:
- Клиент ссылается на наше приложение, используя URL-адрес, например www.ourapp.com/as/www.clientapp.com/then-go-to/path/in/ourapp.
- Приведенный выше URL-адрес направляется методу действия, который записывает файл cookie с именем «skin» со значением «www.clientapp.com», а затем перенаправляет на /path/in/ourapp.
- Наш макет (мастер-страница) имеет
@Html.Action
в разделе<head>
, где должны отображаться файлы css. - Дочернее действие проверяет файл cookie и создает модель представления, которая сообщает частичному представлению, какие
<link>
теги отображать.
Структура файла css основана на значении cookie. Таким образом, наш CSS-контент может выглядеть так:
/content
/www.clientapp.com
/style1.css
/style1.css
/www.client2app.com
/style1.css
/style2.css
Я готов услышать лучшие шаблоны/альтернативы для применения скинов к макету. Однако это не причина моего вопроса.
В настоящее время существует проблема с этим подходом, когда файлы css отсутствуют в файловой системе. Запрос приводит к тому, что IIS возвращает ошибку 404. Мы переопределяем страницу 404 пользовательской страницей (не используя тот же макет, который имеет @Html.Action в <head>
). Это приводит к тому, что IIS выполняет некоторую дополнительную обработку, которая не является необходимой (например, частичные и дочерние действия для отображения ссылок входа/выхода, горизонтальной навигации и т. д. в макете страницы 404).
Как я вижу, есть 2 способа решить эту проблему:
- В дочернем действии, которое настраивает css, убедитесь, что файлы существуют на диске, прежде чем сообщать модели представления, что они должны быть отображены. Плюс этого подхода в том, что он должен быть довольно простым. Минусы заключаются в том, что для модульного тестирования потребуется обернуть файловый ввод-вывод в службу, которую можно внедрить. Также приложение будет развернуто в Azure. Я думаю, что Azure может читать файловую систему (что и нужно), но не может писать в нее.
- Каким-то образом предотвратить возврат 404 для файлов css. Чтобы сделать это, мы должны были бы реализовать логику в global.asax Application_Error? Или есть другой способ предотвратить отсутствующие файлы CSS, вызывающие ответ 404?
Какой подход правильный? Или есть что-то другое, что я не рассматриваю?
Обновить
В итоге мы решили это на пользовательской странице ошибки 404 следующим образом:
[ActionName("not-found")]
public virtual ActionResult NotFound()
{
// do not return 404 for missing css files
if (Request.RawUrl.EndsWith(".css", StringComparison.OrdinalIgnoreCase))
{
Response.StatusCode = 404;
return new EmptyResult();
}
return View();
}