在我的ASP.NET MVC网站的区域中执行全局视图数据的最佳方法? [英] Best way to do global viewdata in an area of my ASP.NET MVC site?

查看:43
本文介绍了在我的ASP.NET MVC网站的区域中执行全局视图数据的最佳方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个控制器,我希望每个ActionResult返回相同的视图数据.在这种情况下,我知道我将永远需要基本的产品和员工信息.

I have an several controllers where I want every ActionResult to return the same viewdata. In this case, I know I will always need basic product and employee information.

现在我正在做这样的事情:

Right now I've been doing something like this:

public ActionResult ProductBacklog(int id)  {
      PopulateGlobalData(id);
      // do some other things
      return View(StrongViewModel);
}

其中PopulateGlobalData()定义为:

Where PopulateGlobalData() is defined as:

    public void PopulateGlobalData(int id) {
        ViewData["employeeName"] =  employeeRepo.Find(Thread.CurrentPrincipal.Identity.Name).First().FullName;
        ViewData["productName"] = productRepo.Find(id).First().Name;
     }

这只是伪代码,因此可以原谅任何明显的错误,是否有更好的方法来做到这一点?我想到让我的控制器继承一个类,该类几乎可以执行与您在此处看到的相同的操作,但是我没有看到任何好处.感觉我在做的事是错误的并且难以维护,解决这个问题的最佳方法是什么?

This is just pseudo-code so forgive any obvious errors, is there a better way to be doing this? I thought of having my controller inherit a class that pretty much does the same thing you see here, but I didn't see any great advantages to that. It feels like what I'm doing is wrong and unmaintable, what's the best way to go about this?

推荐答案

您可以编写自定义

You could write a custom action filter attribute which will fetch this data and store it in the view model on each action/controller decorated with this attribute.

public class GlobalDataInjectorAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        string id = filterContext.HttpContext.Request["id"];
        // TODO: use the id and fetch data
        filterContext.Controller.ViewData["employeeName"] = employeeName;
        filterContext.Controller.ViewData["productName"] = productName;
        base.OnActionExecuted(filterContext);
    }
}

当然,使用基本视图模型和强类型视图会更加干净:

Of course it would much cleaner to use a base view model and strongly typed views:

public class GlobalDataInjectorAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        string id = filterContext.HttpContext.Request["id"];
        // TODO: use the id and fetch data
        var model = filterContext.Controller.ViewData.Model as BaseViewModel;
        if (model != null)
        {
            model.EmployeeName = employeeName;
            model.ProductName = productName;
        }
        base.OnActionExecuted(filterContext);
    }
}

现在剩下的就是用此属性装饰基本控制器了:

Now all that's left is to is to decorate your base controller with this attribute:

[GlobalDataInjector]
public abstract class BaseController: Controller
{ }


我个人更喜欢另一个有趣的解决方案,它涉及到子动作.在这里,您定义一个控制器来处理此信息的检索:


There's another more interesting solution which I personally prefer and which involves child actions. Here you define a controller which handles the retrieval of this information:

public class GlobalDataController: Index
{
    private readonly IEmployeesRepository _employeesRepository;
    private readonly IProductsRepository _productsRepository;
    public GlobalDataController(
        IEmployeesRepository employeesRepository,
        IProductsRepository productsRepository
    )
    {
        // usual constructor DI stuff
        _employeesRepository = employeesRepository;
        _productsRepository = productsRepository;
    }

    [ChildActionOnly]
    public ActionResult Index(int id)
    {
        var model = new MyViewModel
        {
            EmployeeName = _employeesRepository.Find(Thread.CurrentPrincipal.Identity.Name).First().FullName,
            ProductName = _productsRepository.Find(id).First().Name;
        };
        return View(model);
    }
}

现在剩下的就是包括,只要需要(如果是全局的,则可能是母版页):

And now all that's left is to include this wherever needed (probably the master page if global):

<%= Html.Action("Index", "GlobalData", new { id = Request["id"] }) %>

或如果ID是路线的一部分:

or if the id is part of the routes:

<%= Html.Action("Index", "GlobalData", 
    new { id = ViewContext.RouteData.GetRequiredString("id") }) %>

这篇关于在我的ASP.NET MVC网站的区域中执行全局视图数据的最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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