Asp.net MVC 3全球查询?

时间:2011-09-08 21:53:59

标签: asp.net asp.net-mvc routing query-string

我正在为两个业务组构建通用Web应用程序。徽标/横幅需要根据查询字符串进行更改。例如,如果网址为http://foo.com/test?bg=a,则会显示商家分组a的徽标,如果网址为http://foo.com/test?bg=b,则会显示商家分组b的徽标。如果我只有一个动作,这不是问题。但我有很多行动。

我可以检查所有操作的查询字符串,但必须有一个很好的方法来执行它。我有一种感觉,我需要做一些路由的东西,但只是不知道如何。谁能告诉我怎么做?

4 个答案:

答案 0 :(得分:6)

您可以撰写Custom Routing Handler并使用路由提取querystring作为参数,并传递到RouteData,可以在任何地方访问。

public class RouteWithQueryStringValueHandler : MvcRouteHandler
{
    private readonly string key;

    public RouteWithQueryStringValueHandler(string key)
        : base()
    {
        this.key = key;
    }

    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        var request = requestContext.HttpContext.Request;
        var qsValue = requestContext.HttpContext.Request[key];
        var router = base.GetHttpHandler(requestContext);
        requestContext.RouteData.DataTokens[key] = qsValue;
        return router;
    }
}

注册如下:

routes.Add(new Route("{controller}/{action}/{id}", 
                 new RouteValueDictionary(
                         new { controller = "Home", 
                               action = "Index",
                               id = UrlParameter.Optional 
                         }),
                 new RouteWithQueryStringValueHandler("bg")));

获取路由数据的徽标:

var logo = RouteData.DataTokens["bg"];

答案 1 :(得分:1)

您可以编写一个自定义帮助器方法,该方法基于查询字符串参数将给定的类附加一个div。那么你当然会在你的CSS文件中使用背景图像进行不同的类定义。

例如:

public static class HtmlExtensions
{
    public static string BannerClass(this HtmlHelper html)
    {
        var bg = html.ViewContext.Controller.ValueProvider.GetValue("bg");
        if (bg == null || string.IsNullOrEmpty(bg.AttemptedValue))
        {
            // no bg parameter => return a default class
            return "default_banner";
        }

        if (string.Equals("a", bg.AttemptedValue))
        {
            return "banner_a";
        }
        else if (string.Equals("b", bg.AttemptedValue))
        {
            return "banner_b";
        }

        // unknown value for the bg parameter => return a default class
        return "default_banner";
    }
}

然后在你的_Layout中,您可以将此课程应用于某个占位符,例如div甚至是正文:

<div class="@Html.BannerClass()">OK</div>

这样,它将始终应用于应用程序中的所有视图。

现在剩下的就是为不同的横幅定义CSS规则:

.default_banner {
    background-image: url('../images/default_banner.png')
}

.banner_a {
    background-image: url('../images/banner_a.png')
}

.banner_b {
    background-image: url('../images/banner_b.png')
}

答案 2 :(得分:0)

如果您正在使用Razor(我相信这确实打破了职责分离指南),请更改_ViewStart.cshtml来执行此操作。

@{
    if (/* Context.QueryString Params, not at my development box*/)
    {
        Layout = "~/Views/Shared/Layout-Group1.cshtml";
    }
    else
    {
        Layout = "~/Views/Shared/Layout-Group2.cshtml";
    }
}

我更喜欢这条路线,因为它可以使任何未来的请求(布局+ css + javascript)相当容易,因为它们都可以在布局中更新。

答案 3 :(得分:0)

在主页面中放置一些代码,以根据查询字符串决定显示哪个横幅。理想情况下,代码不是完全内联的,即它在辅助类中。