c# - 在每个 View 中包含用户模型

标签 c# asp.net asp.net-mvc asp.net-mvc-4

我正在创建一个带有 Forms 身份验证的 ASP.NET MVC4 网站,但在以正确的方式在一个 View 中包含多个模型时遇到了困难。

具体来说,有一个属于给定 View 的模型,比如“CartModel”。但是,鉴于网站的当前 UI,在包含有关当前登录用户的信息的主布局 View 中包含的局部 View 中使用了一个模型。

我目前解决此问题的方法是将 LoginModel 作为每个 View 模型的一部分包含在内。但是,这似乎是重复的并且无法正常工作。

解决此类问题的最正确方法是什么?

最佳答案

有两种方法可以使其易于访问。

  1. 使用过滤器(或覆盖所有 Controller 派生自的基本 Controller 中的 OnActionExecuting 方法),将您需要的模型添加到 ViewBag/ViewData
  2. 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/

相关文章:

javascript - 在每个加载和发布的网站上显示加载 gif?

asp.net - 使用 Visual Studio 2010 时加密配置文件部分 'Web Deploy'

c# - 使用 DotNetZip 通过响应将 Zip 文件发送到客户端

ASP.NET MVC : How to use static HTML pages in MVC applications?

c# - 防止单元格级制表位,但仍允许行在 WPF DataGrid 中具有制表位

c# - 转义 String.Format 占位符

javascript - Kendo菜单一次选择多个项目,ASP.NET MVC

c# - 基于 Active Directory 为网站开发登录页面

c# - 从 String textBox 到 hex 0x byte[] c#

c# - asp.net mvc 遗留路由映射