tags:

views:

253

answers:

3

Hi All,

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.

A: 

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.

Ariel Popovsky
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.
WDuffy
A: 

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.
    }
Robert Harvey
+1  A: 

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);
        }

    }
}
WDuffy