mitchellJ
mitchellJ

Reputation: 734

Passing one parameter of multiple to controller

I'm trying to sort a list while maintaining the page number currently being viewed. I've created a pagehelper class and sorthelper class to do so. The problem is that instead of passing just the parameter the controller needs it's passing the entire end of the URL. How do I route it so that just the correct parameter is passed?

sorthelper.cs:

public static MvcHtmlString PageSort
    (this HtmlHelper html, string LinkText, string sortOrder, string Category, PagingInfo pagingInfo, Func<int, string> pageUrl)
{
    //Ref to Models.PagingInfo to get number of pages

    StringBuilder result = new StringBuilder();
    {

        //Constructs the href per page
        TagBuilder tag = new TagBuilder("a"); // Construct an <a> tag

        tag.MergeAttribute("href", "?sortOrder=" + sortOrder + pageUrl(pagingInfo.CurrentPage));

        tag.InnerHtml = LinkText;

        tag.AddCssClass("selected");
        result.Append(tag.ToString());
    }

    //Dynamically creates links - String as href+pagenumber=URL
    return MvcHtmlString.Create(result.ToString());
}

Link from Entries.cshtml:

 @Html.PageSort("Case", "Case", Model._CurrentCategory, Model.PagingInfo, x=> Url.Action("Entries",
            new { page = Model.PagingInfo.CurrentPage, category = Model._CurrentCategory}))

Route:

        routes.MapRoute(null, "{category}/{sortOrder}/Page{page}", new
    {
        controller = "Entry",
        action = "Entries"
    },
       new { sortOrder = @"\[A-Z]", page = @"\d+" }
    );

When I sort I get the following link:

http://SNIP:7511/?sortOrder=Case/?page=1

The parameter needed in this instance would simply be "Case" but instead I'm getting "Case/?page=1". My initial thought is to filter the url with a Regex in the controller itself but I have a feeling I'm over-complicating it and possibly not utilizing the routeconfig correctly.

Is this supposed to be handled by routing, the controller, or the helper object? How?

Thanks!

EDIT Thank you for the information. Apparently I was over-complicating it.

<th>@Html.RouteLink("Case", "", new {category = Model._CurrentCategory, sortOrder = "Case", page = Model.PagingInfo.CurrentPage })</th>

This worked but apparently my db is leaving trailing spaces in all entries so that is a separate issue I will have to tackle.

Upvotes: 1

Views: 83

Answers (1)

Ben Aaronson
Ben Aaronson

Reputation: 6975

In a route of form {category}/{sortOrder}/Page{page}, with base URL http://SNIP:7511/, the correct route for category "default", sort order "Case", page "1" would be:

http://SNIP:7511/default/Case/Page1

Note that you don't need to specify the variable name in the URL itself, this is precisely what the routing does- it specifies how the parts of the URL should be mapped to variables (as well as directing to the correct controller and action).

The ?sortOrder= form is actually a different way of achieving variable passing. In this form, you would not include sortOrder in your route, but you would have it as a parameter to your Action method. These can only come in the last part of your URL, so for example if you specifically wanted to have sortOrder in this form you would have to change your route to something like:

{category}/Page{page}

And your URL would be:

http://SNIP:7511/default/Page1?sortOrder=Case

Also note that you generally shouldn't be assembling URLs yourself. There are in-built Helper methods like HtmlHelper's ActionLink which will do this for you, automatically keeping the actual URLs in the site consistent with how you've set up your routes.

Upvotes: 1

Related Questions