Вопрос

Я пытаюсь внедрить пользовательский механизм просмотра для обслуживания мобильных представлений на основе пользовательского агента. Я следую подходу Скотта Хансельмана из этой записи блога .

Я унаследовал от 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, и естественно, что метод во вложенном классе никогда бы не был вызван!

Урок: при использовании кода, найденного в сети, не копируйте и не вставляйте! Всегда вводите это самостоятельно.

Спасибо всем, кто проверил этот вопрос и попытался мне помочь.

Теперь я пойду и встану в угол стыда и смущения!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top