ASP。NET MVC -在基本控制器中為母版設置視圖數據

[英]ASP.NET MVC - Set ViewData for masterpage in base controller


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.

我在ASP中使用了masterpage。凈MVC項目。這個母版希望出現一些ViewData,它會在每個頁面上顯示這些數據。

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鍵,我就會得到一個它找不到的錯誤。但是,我不想在每個控制器中設置ViewData(我不想說ViewData["foo"] = GetFoo();在每個控制器)。

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.

我想在基控制器中設置這個,讓每個控制器繼承這個基控制器。在基本控制器默認構造中,我設置了ViewData。我在這里發現了一個類似的方法:http://www.asp.net/learn/MVC/tutorial-13-cs.aspx。到目前為止,一切都很好。但問題是這些數據來自某個數據庫。

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).

現在當我想要單元測試我的控制器時,從基控制器繼承的那些調用它的默認構造函數。在默認的構造函數中,我初始化存儲庫類,以便從數據庫中獲取數據。結果:我的單元測試失敗,因為它不能訪問數據(我當然不希望他們訪問這些數據)。

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?

我也不希望將正確的存儲庫(或DataContext,無論您如何命名)傳遞給每個控制器,而這些控制器又將其傳遞給默認的控制器,然后我可以用單元測試來模擬這個控制器。控制器反過來依賴於其他存儲庫類,最后我將把多個參數傳遞給構造函數。對我的感覺來說,工作太多了,還是我錯了?有另一個解決方案嗎?

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,但最后我覺得這並不能解決我的問題,因為每個控制器仍然需要調用基構造函數來初始化存儲庫類,所以我不能模仿它。

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!

這是一個類似的問題,但我沒有找到令人滿意的答案。我可以用一種簡潔的方式來解決這個問題嗎?或許可以用StructureMap作為解決方案?或者我應該讓jsut吸取它並將一個存儲庫傳遞給每個控制器,然后再將它傳遞給基控制器?再一次,對於如此簡單的事情來說,這就像做了那么多的工作。謝謝!

1 个解决方案

#1


45  

I see two options:

我看到兩個選擇:

First:

第一:

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

在basecontroller . onactionexecution()或basecontroller . onactionperformed()中設置主頁的視圖數據:

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

Second:

第二:

Or create custom filter:

或創建自定義過濾器:

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.

我認為第二種解決方案完全適合你的情況。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2009/06/10/724e731a11bcf013aace9764be3d8fd.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com