当前位置: 动力学知识库 > 问答 > 编程问答 >

asp.net mvc 3 - How to persist a complex query string while paging using Html.RouteLink in MVC3

问题描述:

I have a specialized search engine that passes search criteria from the Search page (form) to the Results page via a long and complex query string (37 parameters) in the URL. It must be done this way rather than as a form post because I want to give users the ability to author their own search queries by constructing custom URLs.

I'm handling the paging as a parameter in the URL and not as part of the query string. So for example "/Search/Results?keyword=&..." directs to page 1, and "/Search/Results/6?keyword=&..." directs to page 6, etc. I'm looking for a way to persist the query string across the pages, but I can't seem to find a way for RouteLink to "reattach" the incoming query string to the URL it generates. Some posts I've seen suggest explicitly attaching each parameter as "new { }", but there are 37 of them so that way wouldn't be practical.

What I'd really like to find is something like;

Html.RouteLink("Next", "Default", new { controller = "Search", action = "Results", page = nextPage, Request.QueryString });

but that doesn't work.

Any suggestions?

网友答案:

That's a good candidate for a custom html helper:

public static class HtmlExtensions
{
    public static IHtmlString MyRouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, object routeValues)
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
        var request = htmlHelper.ViewContext.HttpContext.Request;
        var url = urlHelper.RouteUrl(routeName, routeValues, request.Url.Scheme);
        var uriBuilder = new UriBuilder(url);
        var query = HttpUtility.ParseQueryString(string.Empty);
        foreach (string key in request.QueryString.Keys)
        {
            query[key] = request[key];
        }
        var routeQuery = HttpUtility.ParseQueryString(uriBuilder.Query);
        foreach (string key in routeQuery)
        {
            query[key] = routeQuery[key];
        }
        uriBuilder.Query = query.ToString();
        var anchor = new TagBuilder("a");
        anchor.Attributes["href"] = uriBuilder.ToString();
        anchor.SetInnerText(linkText);
        return new HtmlString(anchor.ToString());
    }
}

which you would use in your view:

@Html.MyRouteLink(
    "Next", 
    "Default", 
    new { 
        controller = "Search", 
        action = "Results", 
        page = nextPage
    }
)
网友答案:

How about this:

<a href="@Url.RouteUrl(new 
        {
            controller = "Search", 
            action = "Results", 
            page = nextPage
         }
     )[email protected]">Next</a>
网友答案:

Create a ActionLink Extension which will add querystring to route values, like..

public static class LinkExtensions
    {
        public static string MyActionLink(this HtmlHelper helper,string actionName,string controllerName,string linkText)
        {
            var qs =helper.ViewContext.HttpContext.Request.QueryString;
            RouteValueDictionary dict=new RouteValueDictionary();
            qs.AllKeys.ToList().ForEach(k=>dict.Add(k,qs[k]));

            UrlHelper urlhelper = new UrlHelper(helper.ViewContext.RequestContext);

            string url = urlhelper.Action(actionName, controllerName, dict);
            TagBuilder tagBuilder = new TagBuilder("a")
            {
                InnerHtml = (!String.IsNullOrEmpty(linkText)) ? HttpUtility.HtmlEncode(linkText) : String.Empty
            };
            tagBuilder.MergeAttribute("href", url);
            return tagBuilder.ToString(TagRenderMode.Normal);

        }
    }

In the view you can use it as,

@Html.MyActionLink("Index","Home","link to Home")

分享给朋友:
您可能感兴趣的文章:
随机阅读: