ASP.NET MVC Custom View Engine не вызывается
-
06-07-2019 - |
Вопрос
Я пытаюсь внедрить пользовательский механизм просмотра для обслуживания мобильных представлений на основе пользовательского агента. Я следую подходу Скотта Хансельмана из этой записи блога .
Я унаследовал от WebFormsViewEngine и переопределил метод FindView так же, как Скотт описывает в своем блоге.
Затем я добавил несколько строк в мой метод Global.asax Application_Start, чтобы очистить коллекцию механизма просмотра и добавить новый экземпляр моего механизма представления. Р>
После некоторого тестирования может показаться, что MVC игнорирует мой механизм просмотра. Когда он не смог найти мои пользовательские представления, основанные на пользовательском агенте браузера, я прибегнул к жесткому программированию пользовательского пути, чтобы добавить его к представлению, и ему все же удалось вернуться к представлению по умолчанию. Я установил точку останова в своем методе FindView и, конечно же, он вообще не вызывается.
Как я могу заставить мой собственный механизм просмотра работать? Любая помощь будет высоко ценится.
Мой движок вида выглядит следующим образом:
public class MyViewEngine: WebFormsViewEngine
{
public override ViewEngineResult FindView (ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
ViewEngineResult result = null;
//Serve a special view for iPhones
if (UserAgentIs(controllerContext, "iPhone"))
{
result = base.FindView(controllerContext, "Mobile/iPhone/" + viewName, masterName, useCache);
}
//If no special view is found, fall back to the default view
if (result == null || result.View == null)
{
result = base.FindView(controllerContext, viewName, masterName, useCache);
}
return result;
}
private bool UserAgentIs(ControllerContext controllerContext, string userAgentToTest)
{
return (controllerContext.HttpContext.Request.UserAgent.IndexOf(userAgentToTest, StringComparison.OrdinalIgnoreCase) > 0);
}
}
И в моем Global.asax:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new MyViewEngine());
}
Когда эта настройка не работала, я даже пытался упростить свой метод FindView до этого:
public override ViewEngineResult FindView (ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
ViewEngineResult result = null;
result = base.FindView(controllerContext, "Mobile/iPhone/" + viewName, masterName, useCache);
return result;
}
И это тоже не сработало. Это все еще возвратило представление по умолчанию. И да, страница просмотра и главная страница, которые должны быть найдены этим утверждением, действительно существуют. Я довольно озадачен тем, почему это не работает. Р>
Решение
Ну, это, конечно, смущает:
Когда я писал свой механизм просмотра, я следил за сообщением в блоге Скотта Хансельмана (см. ссылку на мой оригинальный пост). Я удалил свой класс из механизма представления, а затем решил, что просто скопирую и вставлю код Скотта в свой класс и внесу в него необходимые изменения. Я случайно скопировал его код С определения класса в мой класс, создав вложенный класс. Поэтому мой движок представления на самом деле не содержал переопределения для метода FindView, и естественно, что метод во вложенном классе никогда бы не был вызван! Р>
Урок: при использовании кода, найденного в сети, не копируйте и не вставляйте! Всегда вводите это самостоятельно.
Спасибо всем, кто проверил этот вопрос и попытался мне помочь. Р>
Теперь я пойду и встану в угол стыда и смущения! Р>