Asp.net mvc ASP.NET MVC-在基本控制器中为母版页设置ViewData

Asp.net mvc ASP.NET MVC-在基本控制器中为母版页设置ViewData,asp.net-mvc,controller,master-pages,Asp.net Mvc,Controller,Master Pages,我正在ASP.NETMVC项目中使用母版页。此母版页希望显示一些ViewData,这些ViewData会在每页上显示 如果我没有在我的控制器中设置这个ViewData键,我会得到一个它找不到的错误。但是,我不想在每个控制器中设置ViewData(我不想在每个控制器中说ViewData[“foo”]=GetFoo();) 所以,我想在一个基本控制器中设置它,让每个控制器都继承这个基本控制器。在基本控制器默认构造函数中,我设置了ViewData。我在这里发现了一个类似的方法:到目前为止很好,这是可行

我正在ASP.NETMVC项目中使用母版页。此母版页希望显示一些ViewData,这些ViewData会在每页上显示

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

所以,我想在一个基本控制器中设置它,让每个控制器都继承这个基本控制器。在基本控制器默认构造函数中,我设置了ViewData。我在这里发现了一个类似的方法:到目前为止很好,这是可行的。。。但问题是这些数据来自某个地方的数据库

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

我也不想将正确的存储库(或DataContext,不管你叫它什么)类传递给每个控制器,而这些控制器又将其传递给默认控制器,然后我可以用我的单元测试对其进行模拟。控制器反过来依赖于其他存储库类,我最终会将多个参数传递给构造函数。对我的感觉来说工作太多了,还是我错了?还有别的解决办法吗

我曾经尝试过使用StructureMap,但最终我觉得这并不能解决我的问题,因为每个控制器仍然需要调用基本构造函数来初始化存储库类,所以我不能模拟它

这是一个类似的问题,但我发现没有给出令人满意的答案。我能用一种简洁的方式解决这个问题吗,也许可以使用StructureMap作为解决方案?或者我应该把它吸进去,把一个存储库传递给每个控制器,然后再把它传递给基本控制器吗?再一次,对于这么简单的事情,感觉有这么多的工作要做。谢谢

我看到两种选择:

第一名:

在BaseController.OnActionExecuting()或BaseController.OnActionExecuted()中设置母版页的ViewData:

秒:

或创建自定义筛选器:

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"] = ...
    }
}
然后应用于控制器:

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

我认为第二种解决方案正适合你的情况。

hmm,这看起来很有希望。我现在在家,所以明天会测试这个,尽管我确实觉得第二个会起作用(祈祷吧,我已经花了太多时间尝试各种事情了)。我喜欢AOP风格,我在我的项目中使用了第二种解决方案,而且很有效smoothly@eu-ge ne:直到看到您的代码片段,我才完全理解如何(或何时)使用ActionFilters。我可以想象它们现在有很多用途我已经将我的实现从使用类似的体系结构切换到您的“第一”方法,现在我使用ActionFilter方法。它工作得很好,并且在我的基础控制器中清理了很多其他的污水。谢谢你的回答!是否可以在操作级别上设置属性,或者我是否必须实现过滤器?是的,您可以在控制器级别或操作级别上设置属性
[DataForMasterPage]
public class YourController : YourBaseController
{
    ...
}