当用户登录我的应用程序时,我想在整个应用程序中显示他的名字。我正在使用 asp.net MVC 框架。但我不想要的是必须在每个控制器中放入类似的东西:
ViewData["User"] = Session["User"];
这是因为您可能不会重复自己。(我相信这是 OO 编程的 DRY [Don't Repeat Yourself] 原则。) ViewData["User"] 在我的主页上。所以我的问题是,在一个地方处理我的 ViewData["User"] 的巧妙方法是什么?
当用户登录我的应用程序时,我想在整个应用程序中显示他的名字。我正在使用 asp.net MVC 框架。但我不想要的是必须在每个控制器中放入类似的东西:
ViewData["User"] = Session["User"];
这是因为您可能不会重复自己。(我相信这是 OO 编程的 DRY [Don't Repeat Yourself] 原则。) ViewData["User"] 在我的主页上。所以我的问题是,在一个地方处理我的 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
{...}
已经一年了,但我刚刚偶然发现了这个问题,我相信有一个更好的答案。
Jimmy Bogard 将接受的答案中描述的解决方案描述为反模式,并提供了一个更好的解决方案,包括RenderAction
:http ://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/18/the-filter-viewdata-反模式.aspx
使用 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) %>
另见:
在整个应用程序中提供持久模型数据的另一种方法是用您的自定义控制器覆盖 DefaultFactoryController。在您的 CustomerFactoryController 中,您可以将 ViewBag 与您想要保留的模型相结合。