C#在MVC中集中重复的视图数据

C#在MVC中集中重复的视图数据,c#,asp.net-mvc,viewdata,C#,Asp.net Mvc,Viewdata,当用户登录到我的应用程序时,我希望在整个应用程序中显示他的姓名。我正在使用asp.NETMVC框架。但我不想让每个控制器都像这样: ViewData["User"] = Session["User"]; 这是因为你可能不会重复你自己。(我相信这就是OO编程的枯燥(不要重复)原则。) ViewData[“用户”]位于我的母版页上。因此,我的问题是,在一个地方处理我的ViewData[“User”]有什么好方法?在控制器基类或应用于控制器/操作的操作过滤器中,您可以非常轻松地完成这项工作。在任何一

当用户登录到我的应用程序时,我希望在整个应用程序中显示他的姓名。我正在使用asp.NETMVC框架。但我不想让每个控制器都像这样:

ViewData["User"] = Session["User"];
这是因为你可能不会重复你自己。(我相信这就是OO编程的枯燥(不要重复)原则。)
ViewData[“用户”]位于我的母版页上。因此,我的问题是,在一个地方处理我的ViewData[“User”]有什么好方法?

在控制器基类或应用于控制器/操作的操作过滤器中,您可以非常轻松地完成这项工作。在任何一种情况下,您都有机会在操作之前(或之后)触摸请求,因此您可以在那里添加此功能

例如:

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
{...}

使用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) %>

另见


    • 已经一年了,但我刚刚偶然发现了这个问题,我相信有更好的答案


      Jimmy Bogard将公认答案中描述的解决方案描述为一种反模式,并提供了一种更好的解决方案,包括
      渲染

      在整个应用程序中提供持久模型数据的另一种方法是用自定义的方法覆盖DefaultFactoryController。在CustomerFactoryController中,您可以将ViewBag与要持久化的模型混合

      Thnx,我将尝试基类。但是为什么要重写OnActionExecuting()方法呢?这个方法有什么作用?它的目的是什么?它在您的操作(方法)执行之前执行。如果需要,可以使用OnActionExecuted,它在执行操作后立即执行。好的,因为我把它放在基类中,它会影响控制器中的所有操作?正确。这同样适用于操作过滤器方法,您将
      [UserInfo]
      放在类级别(而不是方法级别)。“检查模型是否从BaseModel派生,以及..”我如何做到这一点?你能给我举个例子吗?我想我明白你的答案了。但我知道这不是有点复杂吗?Marc Gravell的公共基类在某种程度上不是做同样的事情吗?@Martijn,它允许您使用强类型模型而不是ViewData[…]字典。有了它,您的视图中就有了智能支持等@KonstantinTarkus-这不应该是
      var modelBase=ViewData.Model as BaseModel