Генерация URL на основе текущего URL и поддержка QueryString - PullRequest
2 голосов
/ 19 января 2012

У меня есть частичное представление для отображения списка элементов, я использую это частичное представление в нескольких разных местах.В этом частичном представлении я использую paginator -

@Html.PagedListPager(Model, page => Url.Action(null, new { page = page }))

Это приводит к тому, что paginator показывает URL страницы для любого действия и вида, на которые я уже смотрю.страница Я использую строку запроса для строки поиска, а метод Url.Action не включает существующие параметры строки запроса.

Вместо / Search? s = bla & page = 3 Я получаю / Search? page = 3

Как создать URL-адрес с использованием существующей строки запроса?

Редактировать:

Вот мой код

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


        routes.Add(
        "Search",
        new SearchRoute("Search", new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(
                new { controller = "Search", action = "Index" })
        }); 


        routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Call", action = "Index", id = UrlParameter.Optional }


        );



    }

    public class SearchRoute : Route
    {
        public SearchRoute(string url, IRouteHandler routeHandler)
            : base(url, routeHandler)
        {
        }

        public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        {

            System.Diagnostics.Debug.WriteLine(Url);

            if (HttpContext.Current != null)
            {

                string s = HttpContext.Current.Request.QueryString["s"];

                if (!string.IsNullOrEmpty(s))
                    values.Add("s", s);

            }

            return base.GetVirtualPath(requestContext, values);
        }
    }

Ответы [ 2 ]

3 голосов
/ 19 января 2012

Используя пользовательский маршрут, вы можете сохранить строку запроса, потому что большая часть логики генерации URL использует маршрут для генерации URL.В этом случае я проверяю объект запроса на строку запроса с именем XXX и добавляю ее в маршрут, если он существует, вы можете сделать его более универсальным, если хотите.в global.ascx (хотя, вероятно, не для такого общего соответствия, как у меня ниже)

        routes.Add(
            "Default",
            new PreserveQueryStringRoute("{controller}/{action}/{id}", new MvcRouteHandler())
            {
                Defaults = new RouteValueDictionary(
                    new { controller = "Home", action = "Index", id = UrlParameter.Optional })
            });   

Edit:

Хорошо, вот обновление .. это исправление ошибкипример того, как зарегистрировать маршрут (см. исправленный код выше для исправления ошибки)

Вот как его зарегистрировать:

    routes.Add(      
    "Search",      
    new SearchRoute("Search", new MvcRouteHandler())      
    {      
        Constraints = new RouteValueDictionary(      
            new { controller = "Search", action = "Index" })      
    }); 
0 голосов
/ 09 января 2014

Вот как я это делаю:

Я реализовал несколько методов расширения для преобразования строки запроса в RouteValueDictionary и установки в нее отдельных элементов:

public static class RouteValueDictionaryExtensions
{
    public static RouteValueDictionary ToRouteValues(this NameValueCollection queryString)
    {
        if (queryString == null || queryString.HasKeys() == false) 
            return new RouteValueDictionary();

        var routeValues = new RouteValueDictionary();
        foreach (string key in queryString.AllKeys)
            routeValues.Add(key, queryString[key]);

        return routeValues;
    }

    public static RouteValueDictionary Set(this RouteValueDictionary routeValues, string key, string value)
    {
        routeValues[key] = value;
        return routeValues;
    }

    public static RouteValueDictionary Merge(this RouteValueDictionary primary, RouteValueDictionary secondary)
    {
        if (primary == null || primary.Count == 0)
        {
            return secondary ?? new RouteValueDictionary();
        }

        if (secondary == null || secondary.Count == 0)
            return primary;

        foreach (var pair in secondary)
            primary[pair.Key] = pair.Value;

        return primary;
    }

    public static RouteValueDictionary Merge(this RouteValueDictionary primary, object secondary)
    {
        return Merge(primary, new RouteValueDictionary(secondary));
    }
}

Это позволяет создавать ссылки, такие как:

Url.RouteUrl(Request.QueryString.ToRouteValues().Set("Key", "Value"))

Или это:

Url.RouteUrl(Request.QueryString.ToRouteValues().Merge(new {key = "value"}))

Я также могу объединить эти методы расширения для достижения большей гибкости:

Url.RouteUrl(Request.QueryString.ToRouteValues().Set("Key", "Value").Set("AnotherKey", "AnotherValue"))
...