ASP.NET MVC - 为基本控制器中的母版页设置ViewData [英] ASP.NET MVC - Set ViewData for masterpage in base controller

查看:272
本文介绍了ASP.NET MVC - 为基本控制器中的母版页设置ViewData的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的ASP.NET MVC项目中使用母版页。

I'm using a masterpage in my ASP.NET MVC project. This masterpage expects some ViewData to be present, which displays this on every page.

如果我没有在我的控制器中设置这个ViewData键,我得到一个错误,它找不到它。但是,我不想在每个控制器中设置ViewData(我不想在每个控制器中说 ViewData [foo] = GetFoo();

If I don't set this ViewData key in my controllers, I get an error that it can't find it. However, I don't want to set the ViewData in every controller (I don't want to say ViewData["foo"] = GetFoo(); in every controller).

所以,我想在一个基本控制器中设置它,并让每个控制器继承这个基本控制器。在基本控制器默认构造函数中,我设置了ViewData。我在这里找到了类似的方法: http://www.asp.net /learn/MVC/tutorial-13-cs.aspx。到目前为止很好,这个工作...但问题是这些数据来自某个地方的数据库。

So, I was thinking of setting this in a base controller, and have every controller inherit from this base controller. In the base controller default constructur, I set the ViewData. I found a similar approach here: http://www.asp.net/learn/MVC/tutorial-13-cs.aspx. So far so good, this works... but the problem is that this data comes from a database somewhere.

现在当我想要单元测试我的控制器,从基本控制器继承的那些调用其默认构造函数。在默认构造函数中,我初始化我的存储库类,以从数据库获取此数据。结果:我的单元测试失败,因为它无法访问数据(我当然不希望他们访问这些数据)。

Now when I want to Unit Test my controllers, the ones that inherit from the base controller call its default constructor. In the default constructor, I initialize my repository class to get this data from the database. Result: my unit tests fail, since it can't access the data (and I certainly don't want them to access this data).

我也不想传递正确的Repository(或DataContext,无论你命名它)类到每个控制器,反过来它传递给默认控制器,然后我可以模仿我的单元测试。控制器反过来依赖其他存储库类,我最终会传递多个参数到构造函数。为我的感觉太多的工作,或我错了吗?还有另一个解决方案吗?

I also don't want to pass the correct Repository (or DataContext, whatever you name it) class to every controller which in turn pass it to the default controller, which I could then mock with my unit tests. The controllers in turn rely on other repository classes, and I would end up passing multiple parameters to the constructor. Too much work for my feeling, or am I wrong? Is there another solution?

我试过使用StructureMap,但最后我不觉得这将解决我的问题,因为每个控制器仍然调用将初始化仓库类的基础构造函数,所以我不能模拟它。

I've tried using StructureMap but in the end I didn't feel like that is going to fix my problem, since every controller will still have to call the base constructor which will initialize the repository class, so I can't mock it.

这是一个类似的问题,但我发现没有给出满意的答案。我可以用一个整洁的方式解决这个问题,也许使用StructureMap作为解决方案?或者应该我jsut吸它,并传递一个存储库到每个控制器,并再次传递到基本控制器?再次,它感觉像这么多的工作,这么简单的东西。谢谢!

This is a similar question but I find no satisfactory answer was given. Can I solve this in a neat way, maybe using StructureMap as a solution? Or should I jsut suck it and pass a Repository to every controller and pass it again to the base controller? Again, It feels like so much work for something so simple. Thanks!

推荐答案

我看到两个选项:

首先:

在YourBaseController.OnActionExecuting()或YourBaseController.OnActionExecuted()中为MasterPage设置ViewData:

Set the ViewData for MasterPage in YourBaseController.OnActionExecuting() or YourBaseController.OnActionExecuted():

public class YourBaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Optional: Work only for GET request
        if (filterContext.RequestContext.HttpContext.Request.RequestType != "GET")
            return;

        // Optional: Do not work with AjaxRequests
        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            return;

        ...

        filterContext.Controller.ViewData["foo"] = ...
    }
}

第二:

public class DataForMasterPageAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Optional: Work only for GET request
        if (filterContext.RequestContext.HttpContext.Request.RequestType != "GET")
            return;

        // Optional: Do not work with AjaxRequests
        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            return;

        ...

        filterContext.Controller.ViewData["foo"] = ...
    }
}

,然后应用到您的控制器:

and then apply to your controllers:

[DataForMasterPage]
public class YourController : YourBaseController
{
    ...
}

我认为第二个解决方案是为你的情况。

I think the second solution is exactly for your case.

这篇关于ASP.NET MVC - 为基本控制器中的母版页设置ViewData的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆