Asp.net MVC 3 глобальная строка запроса? - PullRequest
3 голосов
/ 09 сентября 2011

Я создаю общее веб-приложение для двух бизнес-групп.Логотип / баннер необходимо изменить в зависимости от строки запроса.Например, если URL-адрес http://foo.com/test?bg=a, он показывает логотип для бизнес-группы a, а если URL-адрес http://foo.com/test?bg=b, он показывает логотип для бизнес-группы b.Это не проблема, если бы у меня было только одно действие.Но у меня много действий.

Я мог бы проверить строку запроса для всех действий, но должен быть хороший способ сделать это.У меня есть ощущение, что мне нужно что-то делать с маршрутизацией, но я просто не знаю как.Может кто-нибудь, пожалуйста, дайте мне знать, как это сделать?

Ответы [ 4 ]

6 голосов
/ 09 сентября 2011

Вы можете написать 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 голос
/ 09 сентября 2011

Вы можете написать собственный вспомогательный метод, который на основе параметра строки запроса добавит заданное имя класса к некоторому div. Тогда, конечно, у вас будут разные определения классов в вашем CSS-файле с применением background-image.

Например:

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')
}
0 голосов
/ 09 сентября 2011

Поместите некоторый код в свои главные страницы, чтобы принять решение о том, какой баннер показывать на основе строки запроса. В идеале код не должен быть полностью встроенным, то есть в классе помощника.

0 голосов
/ 09 сентября 2011

Если вы используете 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";
    }
}

Я предпочитаю этот маршрут, потому что он делает любые будущие запросы (layout + css + javascript) довольно легкими, потому что все они могут быть обновлены в Layout.

...