C# Centralizing repeating VIewData in MVC

Deadly 提交于 2020-01-01 10:06:53

问题


When a user log in into my application i want to show his name throughout the whole application. I am using the asp.net MVC framework. But what i don't want is that is have to put in every controller something like:

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

This because you may not repeat yourself. (I believe this is the DRY [Don't Repeat Yourself] principle of OO programming.) The ViewData["User"] is on my masterpage. So my question is, what is a neat way to handle my ViewData["User"] on one place?


回答1:


You can do this fairly easily in either a controller base-class, or an action-filter that is applied to the controllers/actions. In either case, you get the chance to touch the request before (or after) the action does - so you can add this functionality there.

For example:

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

(can also be used at the action (method) level)


or with a common base-class:

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

[HandleError]
public class HomeController : ControllerBase
{...}



回答2:


It's been a year, but I've just stumbled across this question and I believe there's a better answer.

Jimmy Bogard describes the solution described in the accepted answer as an anti-pattern and offers a better solution involving RenderAction: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/18/the-filter-viewdata-anti-pattern.aspx




回答3:


Another method for providing persistent model data through out your entire application is by overriding the DefaultFactoryController with your custom one. In your CustomerFactoryController, you would hydrate the ViewBag with the model you are wanting to persist.




回答4:


Create a base class for your models with UserName property:

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

Create a base class for you controllers and override it's OnActionExecuted method. Within it check if model is derrived from BaseModel and if so, set it's UserName property.

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);
    }
}

Then you will be able to display user's UserName in the view like this:

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

See also:

  • ASP.NET MVC Best Practices, Tips and Tricks


来源:https://stackoverflow.com/questions/759519/c-sharp-centralizing-repeating-viewdata-in-mvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!