如何在ASP.net MVC 4 webapp的每个页面请求中共享一个公共对象?

时间:2013-03-11 18:39:31

标签: asp.net asp.net-mvc asp.net-mvc-4

我来自"常规" asp.net所以我有点(完全)迷失了MVC。

我用自己的asp.net编程模式做了什么:

  • 我有一个自定义类对象代表"页面"及其属性(如mypage.loadJquery,mypage.isLogged,mypage.Title,自定义缓存逻辑等)
  • 这个类在每个ASHX页面上都是实例化的,然后我操作一个stringbuilder来生成HTML并在最后的浏览器中直接吐出它。
    • 在ASHX页面上只有一个请求,我可以使用我的页面对象在顶部实例化,直到最后调用final response.write

现在我正在尝试使用MVC。我"有点"理解M / V / C模型和路由概念。我想保留我的自定义"页面"对象,但我失去了我的页面生命周期,我绝对不知道如何在每次调用的顶部实现我的页面对象ONCE。

我需要在每个模型,控制器,视图,部分视图,htmlhelper中使用这个实例化的ONCE共享对象......

我意识到MVC模式此刻可能让我感到困惑,我怎么能尝试重现我的需求呢?

(非常具体的例子:在每个请求我需要检查用户是否通过他的cookie登录。如果是我往返数据库获取用户信息。那么我需要这些信息在每个模型/控制器上/该应用程序的视图,但当然不想每次回到安全检查和数据库查询,我怎么能在整个mvc cyle上有这些信息?)

2 个答案:

答案 0 :(得分:0)

我创建了很多像这样的项目。基本上,您可以创建一个基本控制器类,其中所有其他控制器都从该类继承。

[Authorize]
public class BaseController : Controller
{

    private Instructor _G_USER = null;

    protected Instructor G_USER 
    {
        get
        {
            if (_G_USER == null)
            {
                _G_USER = Your DB query here
                ViewData["G_USER"] = _G_USER;

            }
            return _G_USER;
        }
    }
}

然后在你的每个孩子课上,你都可以做到

[Authorize]
public class YourController : BaseController
{
    public ActionResult Index()
    {
        if(!G_USER.CAN_DO_THIS)  throw new NoPermissionException();

        return View();
    }
}

要在视图中使用用户,请创建扩展方法。

public static class ExtentionMethods
{
    public static USER G_USER(this ViewPage page)
    {            
        return (USER)page.ViewData["G_USER"];
    }
}

然后在这样的页面中使用

<%=this.G_USER().....%>

答案 1 :(得分:0)

在我的项目中,我创建了接口IViewModel,其中包含我在布局/母版页中需要的所有字段,并设置为模型,以便我可以轻松使用它们:

IViewModel.cs

public interface IViewModel
{
    string Title { get; set; }

    User User { get; set; }
}

Layout.cshtml

@model IViewModel

<html>
    <head>
        <title>@Model.Title</title>
    </head>
    <body>
        @if (Model.User.IsAuthenticated) {
             You are logged as @Model.User.Name
        }
    </body>
</html>

我的所有模型都实现了该接口(或从ViewModelBase继承,该ViewModelBase是该类的默认实现)。另外,我有自定义操作过滤器,用于检查返回的ActionResult是否为(部分)ViewResult,以及它的模型是否实现了我的IViewModel接口并填充该接口中的数据。

public FillViewModelAttribute : ActionFilterAttribute
{
    public override OnActionExecuted(ActionExecutedContext context)
    {
        var viewResult = context.Result as ViewResult;
        if (viewResult != null && viewResult.Model is IViewModel)
        {
            var viewModel = (IViewModel)viewResult.Model;
            // fill data
        }
    }
}