加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

在我的ASP.NET MVC站点区域中执行全局视图数据的最佳方法?

发布时间:2020-12-16 04:33:30 所属栏目:asp.Net 来源:网络整理
导读:我有几个控制器,我希望每个ActionResult返回相同的viewdata.在这种情况下,我知道我将始终需要基本的产品和员工信息. 现在我一直在做这样的事情: public ActionResult ProductBacklog(int id) { PopulateGlobalData(id); // do some other things return Vie
我有几个控制器,我希望每个ActionResult返回相同的viewdata.在这种情况下,我知道我将始终需要基本的产品和员工信息.

现在我一直在做这样的事情:

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

其中PopulateGlobalData()定义为:

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

这只是伪代码,所以原谅任何明显的错误,有没有更好的方法来做到这一点?我想让我的控制器继承一个几乎与你在这里看到的相同的类,但我没有看到任何巨大的优势.感觉我正在做的事情是错误的和不可维护的,最好的方法是什么?

解决方法

您可以编写一个自定义 action filter 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);
    }
}

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

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);
    }
}

现在剩下的就是用这个属性装饰你的基本控制器:

[GlobalDataInjector]
public abstract class BaseController: Controller
{ }

还有另一个更有趣的解决方案,我个人更喜欢并涉及child actions.在这里,您定义了一个处理此信息检索的控制器:

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);
    }
}

现在剩下的就是include这个需要的地方(可能是全球的主页):

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

或者如果id是路由的一部分:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读