我正在创建一个带有 Forms 身份验证的 ASP.NET MVC4 网站,但在以正确的方式在一个 View 中包含多个模型时遇到了困难。
具体来说,有一个属于给定 View 的模型,比如“CartModel”。但是,鉴于网站的当前 UI,在包含有关当前登录用户的信息的主布局 View 中包含的局部 View 中使用了一个模型。
我目前解决此问题的方法是将 LoginModel 作为每个 View 模型的一部分包含在内。但是,这似乎是重复的并且无法正常工作。
解决此类问题的最正确方法是什么?
最佳答案
有两种方法可以使其易于访问。
- 使用过滤器(或覆盖所有 Controller 派生自的基本 Controller 中的
OnActionExecuting
方法),将您需要的模型添加到ViewBag
/ViewData
。 - Use your own base
WebViewPage
公开模型,但您仍然需要填充它。因此,它可能需要访问您的 API 并正确完成,可能需要一些依赖项注入(inject)。
方法一:OnActionExecuting
从基本 Controller 覆盖
public abstract MyBaseController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (User != null && User.Identity.IsAuthenticated) // check if user is logged in if you need to
{
ViewBag.LoginModel = /* add data here */;
}
}
}
然后将其用作基类(或继承的更上一层):
public MyController : MyBaseController
{
//etc.
}
或者使用过滤器
PopulateLoginModelAttribute : ActionFilterAttribute, IActionFilter
{
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.User != null && filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Controller.ViewBag.LoginModel = /* add data here */;
}
this.OnActionExecuting(filterContext);
}
}
然后装饰一个 Controller 类、action 方法,或者添加为全局过滤器。
[PopulateLoginModel] // will be applied to all actions in this controller
public class MyController : Controller // note you can use the normal base type, or whatever you need
{
public ActionResult MyView()
{
return View(new CartModel());
}
}
然后在引用的部分、布局等中使用您放置在 ViewBag
中的模型,但继续使用 Model
作为操作 View 。
在您的 View 中正常访问 ViewBag
(布局也可访问,我在 LoginModel 类型上创建了一个属性值来说明):
<span>@ViewBag.LoginModel.Name</span> <!-- available because of the filter !-->
Number of items in your cart: @Model.Items.Count <!-- the model provided by the action method !-->
ViewBag.LoginModel
将可用于从该 Controller 派生的所有操作,无需额外工作。我建议将其设为一个属性,因为它可以让您更灵活地使用基类以及您想将其应用到哪些 Controller /操作。
方法二:提供自己的WebViewPage基类
您不太可能希望使用自己的 WebPageView 基类。如果您想添加成员以协助处理数据或 View 的任何内容,这非常适合。但它不是添加或以其他方式操作 View 数据或模型的正确位置,尽管这是可能的。
创建 View 基类
public abstract class MyWebViewPage<T> : WebViewPage<T>
{
protected LoginModel GetLoginModel()
{
// you could resolve some dependency here if you need to
return /* add data here */
}
}
然后在您的 View 、部分和布局中使用成员
确保 views 文件夹中的 web.config 已正确更新。
<span>@GetLoginModel().Name</span>
关于c# - 在每个 View 中包含用户模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20672575/