3

I'm using ASP.NET MVC for the first time and so far everything has been going great. However, one little question I was hoping someone could advise me on.

When a page can perform multiple tasks and each is handled on the server by assessing querystring values what is the recommended solutions for building up the querystring over requests.

For example, a list of products the user may sort, page and filter.

The user performs a sort - ?sortcolumn=example

The user changes page on the list - ?sortcolumn=example&page=3

The user performs a filter on the list - ?sortcolumn=example&page=3&filter=expr

The Actionlinks for each of these tasks is totally seperate from the others, so I need the routevalues in all of the Html.ActionLink expressions.

Hoping somone can advise.

3 Answers 3

4

Thanks for the help guys. I ended up creating an extention method on the UrlHelper to easily build urls that require all active url/querystring data to be passed back. I done this because using the stringbuilder would have been way to difficult to start altering urls based on matches in the routing table.

for example /players/defender/4 or players?sortcolumn=defender&page=4

Using this method I can just put everything back into the routing engine and let it worry about which parts of the url are to be mapped to the url, which parts to the querystring.

using System.Web.Routing;

namespace System.Web.Mvc
{
    public static class UrlHelperExtensions
    {
        public static string RouteUrlIncludingQuerystring(this UrlHelper helper)
        {
            return helper.RouteUrlIncludingQuerystring(new RouteValueDictionary());
        }

        public static string RouteUrlIncludingQuerystring(this UrlHelper helper, object routeValues)
        {
            return helper.RouteUrlIncludingQuerystring(new RouteValueDictionary(routeValues));
        }

        public static string RouteUrlIncludingQuerystring(this UrlHelper helper, RouteValueDictionary routeValues)
        {
            RouteValueDictionary v = new RouteValueDictionary();

            foreach (var kvp in helper.RequestContext.RouteData.Values)
                v[kvp.Key] = kvp.Value;

            foreach (var kvp in helper.RequestContext.RouteData.DataTokens)
                v[kvp.Key] = kvp.Value;

            foreach (var key in helper.RequestContext.HttpContext.Request.QueryString.AllKeys)
                v[key] = helper.RequestContext.HttpContext.Request.QueryString[key];

            foreach (var kvp in routeValues)
                v[kvp.Key] = kvp.Value;

            return helper.RouteUrl(v);
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

You can create a single route that hits a particular controller method, and just add parameters to the controller method as needed. If the parameter exists in the querystring, the controller method will pick it up. If the parameter does not exist in the querystring, the parameter in the controller method will simply be null.

Example:

    public ActionResult ProductsBySystemIndex(int manufacturerID, string page, string sortOrder, string filter)
    {
         if (page != null)
         {
             // do something with page
         }
         // etc.
    }

Comments

0

Take a look at the Pager helper from MvcContrib here The approach they use is calling a helper method for link creation that will iterate through the current querystring keys and append the necessary values for page navigation (ignoring the current page but preserving the other params). The sample is very basic since it only works for paging but could be easily extended to include sorting and filtering.

1 Comment

Thanks Ariel, I thought there may have been a cleverer way to do this but it looks like good old stringbuilder is still the way to go.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.