Расширение существующего сайта MVC для передачи новых данных в ViewData для каждого действия - PullRequest
1 голос
/ 13 декабря 2010

У нас есть платформа с белой меткой, построенная на Asp.Net MVC2. В настоящее время сайт имеет 6 контроллеров, а также все основные виды и т. Д., Которые могут позволить ему работать прямо из коробки. Пока что мы построили 5 сайтов из этого, и все это было здорово.

Теперь, однако, у меня есть требование, которое означает, что я должен иметь возможность передавать новый фрагмент данных (в словаре ViewData все будет в порядке) в всех представлений из любого действия. Эти данные выводятся из строки запроса, а затем из файла cookie.

Одной из основных причин этого является возможность добавления дополнительного изображения на главную страницу сайта в зависимости от значения этих данных. Конечно, я мог бы быть очень грязным и поместить код десериализации в главную страницу; но я бы предпочел найти способ убедиться, что он добавляется в ViewData для каждого запроса , который не включает наследование контроллера и переопределение метода действия (!).

Любые идеи с благодарностью!

Ответы [ 2 ]

4 голосов
/ 13 декабря 2010

Вы можете написать атрибут фильтра настраиваемого действия и применить этот атрибут к базовому контроллеру или ко всем действиям, которым необходимо ввести эту информацию:

public class AdditionalViewDataInjectorAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        filterContext.Controller.ViewData["foo"] = "bar";
    }
}

И затем украсить базовый контроллер следующим атрибутом:

[AdditionalViewDataInjector]
public class BaseController: Controller { }

В ASP.NET MVC 3 существует понятие фильтров глобальных действий , поэтому вам даже не нужно иметь базовый контроллер или украшать все ваши действия этим фильтром.Существует обходной путь , позволяющий добиться того же в ASP.NET MVC 2 .Теперь все ваши представления получают это дополнительное свойство в данных представления.

Как уже говорилось, предыдущий - это уродливый обходной путь, и я не рекомендую его (ViewData уродлив).Вы можете взглянуть на помощников Html.Action и Html.RenderAction .Вот как это может выглядеть:

public class MySpecialController: Controller
{
    public ActionResult Index()
    {
        // Here you have access to the request, cookies, session, routes, ...
        var someModel = GetSomeModel();
        return View(someModel);
    }
}

Затем создайте строго типизированный фрагмент, который будет содержать требуемый HTML (~/Views/MySpecial/Index.ascx), и, наконец, включите его в свою главную страницу:

<%= Html.Action("index", "myspecial") %>
0 голосов
/ 13 декабря 2010

Переопределите OnResultExecuting в базовом контроллере и добавьте необходимые данные в свойство ViewData.

public override void OnResultExecuting(ResultExecutingContext ctx) {
    ViewData["title"] = "Hello world!";
    base.OnResultExecuting(ctx);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...