C # Централизация повторяющихся VIewData в MVC - PullRequest
6 голосов
/ 17 апреля 2009

Когда пользователь входит в мое приложение, я хочу показать его имя во всем приложении. Я использую asp.net MVC Framework. Но я не хочу, чтобы каждый контроллер вставлял что-то вроде:

ViewData["User"] = Session["User"];

Это потому, что вы не можете повторяться. (Я считаю, что это принцип СУХОГО [Не повторяй себя] ОО-программирования.) ViewData ["Пользователь"] находится на моей главной странице. Поэтому мой вопрос в том, как аккуратно обработать мои ViewData ["User"] в одном месте?

Ответы [ 4 ]

12 голосов
/ 17 апреля 2009

Вы можете сделать это довольно легко в базовом классе контроллера или в фильтре действий, который применяется к контроллерам / действиям. В любом случае вы получаете возможность прикоснуться к запросу до (или после) действия - так что вы можете добавить эту функцию туда.

Например:

public class UserInfoAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(
        ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);
        filterContext.Controller.ViewData["user"] = "Foo";
    }
}
...
[HandleError, UserInfo]
public class HomeController : Controller
{...}

(также может использоваться на уровне действия (метод))


или с общим базовым классом:

public abstract class ControllerBase : Controller
{
    protected override void OnActionExecuting(
        ActionExecutingContext filterContext)
    {
        ViewData["user"] = "Bar";
        base.OnActionExecuting(filterContext);
    }
}

[HandleError]
public class HomeController : ControllerBase
{...}
5 голосов
/ 04 мая 2010

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

Джимми Богард описывает решение, описанное в принятом ответе, как анти-шаблон и предлагает лучшее решение, включающее RenderAction: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/18/the-filter-viewdata-anti-pattern.aspx

2 голосов
/ 17 апреля 2009

Создайте базовый класс для ваших моделей с помощью свойства UserName:

public abstract class ModelBase
{
    public string UserName { get; set; }
}

Создайте базовый класс для ваших контроллеров и переопределите его метод OnActionExecuted. В нем проверьте, получена ли модель из BaseModel, и если да, установите ее свойство UserName.

public class ControllerBase : Controller
{
    protected override void OnActionExecuted(
        ActionExecutedContext filterContext)
    {
        var modelBase = ViewData.Model as ModelBase;

        if (modelBase != null)
        {
            modelBase.UserName = "foo";
        }

        base.OnActionExecuted(filterContext);
    }
}

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

<%= Html.Encode(Model.UserName) %>

См. Также :

1 голос
/ 17 декабря 2011

Еще один способ предоставления постоянных данных модели во всем приложении - переопределение DefaultFactoryController с вашим пользовательским. В вашем CustomerFactoryController вы бы гидратировали ViewBag с моделью, которую хотите сохранить.

...