Where to put view logic?

北城以北 提交于 2019-12-10 11:09:17

问题


I am a little confused regarding the design patterns of ASP.NET MVC. I have a Masterpage including a partial view that renders breadcrumbs:

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

The thing is, I want the breadcrumb links to work both in production and in my dev environment. So my code in the partial view goes something like this:

<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/");

...

Is this violating the principle of keeping the view "stupid"? Part of my reasoning for extracting this from the masterpage was this principle. Seems that I just moved the problem over to a new view? What is the alternative?


回答1:


Not sure what MVC version you are using. If you are using MVC3, you could create a 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/";

    }
}

This filter could then add a property into your ViewBag (which is a dynamic object), called SiteUrl, in which you set the site url depending on the state you are in.

In your PartialView you would no longer need the if statement, and just call: ViewBag.SiteUrl . In addition any other page will have access to the SiteUrl property.




回答2:


You could put the generation of the breadcrumbs in a child action. This will give you a whole new View and Controller

In the masterpage:

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

MasterController:

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

Create a Crumbs and DebugCrumbs view that will be called local or not.



来源:https://stackoverflow.com/questions/4722173/where-to-put-view-logic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!