在哪里放置视图逻辑?

Posted

技术标签:

【中文标题】在哪里放置视图逻辑?【英文标题】:Where to put view logic? 【发布时间】:2011-01-18 08:59:57 【问题描述】:

我对 ASP.NET MVC 的设计模式有点困惑。我有一个包含呈现面包屑的局部视图的 Masterpage:

<div id="header">
    <strong class="logo"><a href="#">Home</a></strong>
    <% html.RenderPartial("BreadCrumbs"); %>

问题是,我希望面包屑链接在生产环境和我的开发环境中都能正常工作。所以我在局部视图中的代码是这样的:

<p id="breadcrumbs">
    You are here: <a href="http://
    <% if (Request.Url.IsLoopback)
           Response.Write(String.Format("0/1", Request.Url.Host, Request.Url.Segments[1]));
       else
           Response.Write("http://mysite.com/");

...

这是否违反了保持观点“愚蠢”的原则?我从母版页中提取这个的部分原因是这个原则。似乎我只是将问题转移到了新视图?有什么选择?

【问题讨论】:

【参考方案1】:

不确定您使用的是哪个 MVC 版本。如果你使用 MVC3,你可以创建一个 GlobalActionFilter:http://weblogs.asp.net/gunnarpeipman/archive/2010/08/15/asp-net-mvc-3-global-action-filters.aspx

public class ViewBagInjectionFilterAttribute : ActionFilterAttribute

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    
        base.OnResultExecuting(filterContext);

        filterContext.Controller.ViewBag.SiteUrl = filterContext.HttpContext.Request.Url.IsLoopback
                                                       ? String.Format("0/1",
                                                                       filterContext.HttpContext.Request.Url.Host,
                                                                       filterContext.HttpContext.Request.Url.
                                                                           Segments[1])
                                                       : "http://mysite.com/";

    

然后,此过滤器可以将一个名为 SiteUrl 的属性添加到您的 ViewBag(这是一个动态对象)中,您可以在其中根据您所处的状态设置站点 url。

在您的 PartialView 中,您将不再需要 if 语句,只需调用:ViewBag.SiteUrl。此外,任何其他页面都可以访问 SiteUrl 属性。

【讨论】:

【参考方案2】:

您可以将面包屑的生成放在子操作中。这将为您提供一个全新的视图和控制器

在母版页中:

 <%: Html.Action("Crumbs", "Master") %>

主控制器:

 [ChildActionOnly]
 public PartialViewResult Crumbs() 
    if (Request.Url.IsLoopback()) 
       return PartialView("DebugCrumbs");
     else 
       return PartialView("Crumbs");
    
 

创建一个 Crumbs 和 DebugCrumbs 视图,无论是否调用本地。

【讨论】:

不是很干,是吗?也许在控制器中创建 Url 并将其传递给 crumbs 视图会更好。这样你就只有一个视图。 @Gidon,哦,当然为什么不,但这意味着视图必须测试包括额外的测试和逻辑。我喜欢调用包含尽可能少的内容/逻辑的视图。 实际上我建议在控制器中执行逻辑,并将“计算”的 URL 传递给视图(使用 [View]Model、ViewBag 或 ViewData)

以上是关于在哪里放置视图逻辑?的主要内容,如果未能解决你的问题,请参考以下文章

干净的架构——在哪里放置输入验证逻辑? [关闭]

ASP.NET MVC 2 在哪里放置逻辑

在哪里放置业务逻辑,在控制器或服务中? [复制]

在哪里放置需要从数据库中获取数据的域逻辑

laravel 4 视图,在哪里放置基于类的作曲家

在哪里放置根控制器?