Url.Action() includes unwanted parameters, trying to have more control
Asked Answered
C

3

7

I have a link in a page that goes like this:

Url.Action("List", "Item", new { category = "seasons" })

The Route that matches that page also has a parentGroup and group parameters

Ex: /Seasons/Moober/Blue/1 -> /{category}/{parentGroup}/{group}/{id}

The problem is when I am on that page and use Url.Action, it adds all the missing route values even when I try to generate a link to the categories only /{category}, it will still add parentGroup and group.

I have found this post, that suggests doing it like this:

Url.Action("List", "Item", new { category = "seasons", group = "", parentGroup = "" })

But it does not work for me as it removes them from my url but adds them as parameters: /Seasons?parentGroup=Moober&group=Blue

I am using MVC3. Is there a way to force Url.Action() to use only the provided parameters or to cancel the ones I do not want?

Here are the routes.

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
    "ItemFromCategoryParentGroupSubGroup", // Route name
    "{category}/{parentGroup}/{group}/{id}/{language}", // URL with parameters
    new { controller = "Item", action = "Show", page = 1, language = ConfigurationManager.AppSettings["DefaultLanguage"] }, // Parameter defaults
    new
    {
        category = _validCategory,
        parentGroup = _validGroup,
        group = _validChildGroup,
        id = _validItemInChildGroup
    }
);

routes.MapRoute(
    "ItemListFromParentGroup", // Route name
    "{category}/{parentGroup}/{group}/{language}", // URL with parameters
    new { controller = "Item", action = "List", page = 1, language = ConfigurationManager.AppSettings["DefaultLanguage"] }, // Parameter defaults
    new
    {
        category = _validCategory,
        parentGroup = _validGroup,
        group = _validChildGroup
    }
);

routes.MapRoute(
    "ItemWithGroup", // Route name
    "{category}/{group}/{id}/{language}", // URL with parameters
    new { controller = "Item", action = "Show", page = 1, language = ConfigurationManager.AppSettings["DefaultLanguage"] }, // Parameter defaults
    new
    {
        category = _validCategory,
        group = _validGroup,
        id = _validItemInGroup
    }
);

routes.MapRoute(
    "ItemListWithGroup", // Route name
    "{category}/{group}/{language}", // URL with parameters
    new { controller = "Item", action = "List", page = 1, language = ConfigurationManager.AppSettings["DefaultLanguage"] }, // Parameter defaults
    new
    {
        category = _validCategory,
        group = _validGroup
    }
);

routes.MapRoute(
    "ItemListFromCategory", // Route name
    "{category}/{language}", // URL with parameters
    new { controller = "Item", action = "List", page = 1, language = ConfigurationManager.AppSettings["DefaultLanguage"] }, // Parameter defaults
    new
    {
        category = _validCategory
    }
);

Edit:

I have a workaround for the moment that looks like this: Url.RouteUrl("ItemListFromCategory") I am basically forcing the same route that is supposed to be matched by Url.Action("List", "Item", new { category = "seasons" }) And this time no parameters added automatically.

The problem with this is that I am forced to use named routes.

Charissacharisse answered 8/8, 2011 at 6:15 Comment(1)
I can, I just hope they are not too long.Charissacharisse
C
0

In the end I build custom constrainsts for each routes.

http://msdn.microsoft.com/en-us/library/system.web.routing.route.constraints.aspx

I found that it gives almost full controll over whatever we wish to do with our routes.

Charissacharisse answered 23/5, 2012 at 18:40 Comment(0)
B
3

Change your routes

routes.MapRoute(
    "SomeRoute", // Route name
    "/{category}/{parentGroup}/{group}/{id}", 
    new { 
        controller = "DefaultController", 
        action = "DefaultAction", 
        parentGroup = UrlParameter.Optional
        group = UrlParameter.Optional
        id= UrlParameter.Optional
    }
);

Make parentGroup , parentGroup, group optional.

Brnaby answered 8/8, 2011 at 8:37 Comment(2)
you can't have more than one optional parameter, unless you do something like this: haacked.com/archive/2011/02/20/…Pattiepattin
I have used this workaround weblogs.asp.net/imranbaloch/archive/2010/12/26/… for multiple optional and consecutive parameters, however the url generated is still the same in the end, I will try to mix it with frennky's proposed fix.Charissacharisse
S
0

Try declaring other parameters as UrlParameter.Optional during route registration and set default value for those parameters in your action. Eg.

MyAction(string category, string group = "", parentGroup = 0)

Hope this helps.

Saltzman answered 8/8, 2011 at 6:32 Comment(0)
C
0

In the end I build custom constrainsts for each routes.

http://msdn.microsoft.com/en-us/library/system.web.routing.route.constraints.aspx

I found that it gives almost full controll over whatever we wish to do with our routes.

Charissacharisse answered 23/5, 2012 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.