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

前端之家收集整理的这篇文章主要介绍了asp.net-mvc – ASP.NET MVC – 为基本控制器中的母版页设置ViewData前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在我的ASP.NET MVC项目中使用一个母版页。此母版页需要一些ViewData存在,它在每个页面显示

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

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

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

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

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

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

解决方法

我看到两个选项:

第一:

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

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"] = ...
    }
}

然后应用到您的控制器:

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

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

猜你在找的asp.Net相关文章