0

When I pass multiple parameters to a controller action, I get question marks in the parameters like this:

http://localhost:57728/Home/AddAndManageProperties?BaseCategoryId=11&SubCategoryId=14

I want to remove the question marks to be like this:

http://localhost:57728/Home/AddAndManageProperties/BaseCategoryId=11/SubCategoryId=14

here is my code:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

        routes.MapRoute(
          name: "MyRout",
          url: "{controller}/{action}/{BaseCategoryId}/{SubCategoryId}",
          defaults: new { controller = "Home", action = "AddAndManageProperties", BaseCategoryId = UrlParameter.Optional, SubCategoryId = UrlParameter.Optional }
         );


    }
}

And here is the Action Method:

 public ActionResult AddAndManageProperties(int? BaseCategoryId, int? SubCategoryId)
        {
        }

And i call the method AddAndManageProperties by this method

 [HttpPost]
    public ActionResult AddSubCategory(SubCategory subCategory)
    {
        return RedirectToAction("AddAndManageProperties", new { BaseCategoryId = subCategory.BaseCategoryId, SubCategoryId = subCategory.SubCategoryId });
}

I am new to ASP.NET MVC so please help me!

Lucia
  • 203
  • 5
  • 22
  • First you need to remove `BaseCategoryId = UrlParameter.Optional, SubCategoryId = UrlParameter.Optional` - only the last parameter can be optional. Then if you change it to `url: "Home/AddAndManageProperties/{BaseCategoryId}/{SubCategoryId}",` and move it before the default route it will work assuming your method has matching parameter names. –  Jun 25 '16 at 12:05
  • @StephenMuecke Thank you so much for your help :) Can you please kindly write the code so i can understand it ... sorry i am very new in mvc. Thank you – Lucia Jun 25 '16 at 12:08
  • First edit your question to include the signature of your `AddAndManageProperties()` method, and show how your generating the url (I assume your using `@Html.ActionLink()`? –  Jun 25 '16 at 12:09
  • And how are you generating the url - using `@Html.ActionLink()` or is this a `
    ` (with `FormMethod.Get`)
    –  Jun 25 '16 at 12:16
  • @StephenMuecke I edit the question again. – Lucia Jun 25 '16 at 12:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/115586/discussion-between-lucia-and-stephen-muecke). – Lucia Jun 25 '16 at 12:26

3 Answers3

0

That question marks are used for query strings, and they are required because this is how data is assigned to parameters your actions expect. You should not try to remove them, but you could use the [FromBody] attribute, not to send the parameters in query string.

meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
0

Move the MyRout to be before the Default route and change it to

routes.MapRoute(
    name: "MyRout",
    url: "Home/AddAndManageProperties/{BaseCategoryId}/{SubCategoryId}",
    defaults: new { controller = "Home", action = "AddAndManageProperties" }
 );

Note that only the last parameter can be marked UrlParameter.Optional so the method needs to be

public ActionResult AddAndManageProperties(int BaseCategoryId, int SubCategoryId)

for the above route, or

public ActionResult AddAndManageProperties(int BaseCategoryId, int? SubCategoryId)

if you modify the above route definition to

defaults: new { controller = "Home", action = "AddAndManageProperties", SubCategoryId = UrlParameter.Optional }

Note, if you also want to include the text "BaseCategoryId" and "SubCategoryId" in the route, use

url: "Home/AddAndManageProperties/BaseCategoryId/{BaseCategoryId}/SubCategoryId/{SubCategoryId}",
  • It's working Thank you so much :) It's http://localhost:57728/Home/AddAndManageProperties/14/17 Can i make it like this ? http://localhost:57728/Home/AddAndManageProperties/BaseCategoryId/14/SubCategoryId/17 – Lucia Jun 25 '16 at 12:37
  • Sure - Just change it to `url: "Home/AddAndManageProperties/BaseCategory/{BaseCategoryId}/SubCategory/{SubCategoryId}",` (and when you put url's in comments, surround it with backticks :) –  Jun 25 '16 at 12:41
  • Thank you but i tried this and is not working url: "Home/AddAndManageProperties/BaseCategory/{BaseCategoryId}/SubCategory/{SubCateg‌​oryId}", defaults: new { controller = "Home", action = "AddAndManageProperties" } – Lucia Jun 25 '16 at 12:49
  • Yes now it's working :) Thank you so much Stephen :) God bless you :) – Lucia Jun 25 '16 at 13:02
0

Firstly, and most importantly, your routes are in the wrong order and you have multiple possible URLs that result in calling the wrong route. See Why map special routes first before common routes in asp.net mvc for an explanation.

Secondly, routes cannot contain more than one UrlParamter.Optional.

Third, the = sign is only valid within a query string, unless it is encoded. But IMO, you should not use unsafe characters in a URL to avoid all of the headaches that come with them. A better alternative in this case would be to replace the = with a -.

Finally, if you want to truly make the parameters optional, one approach is to provide multiple routes that allow the parameters in certain routes but not others.

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
              name: "BaseCategoryAndSubCategoryId",
              url: "{controller}/{action}/BaseCategoryId-{BaseCategoryId}/SubCategoryId-{SubCategoryId}",
              defaults: new { controller = "Home", action = "AddAndManageProperties" }
        );

        routes.MapRoute(
            name: "BaseCategoryIdOnly",
            url: "{controller}/{action}/BaseCategoryId-{BaseCategoryId}",
            defaults: new { controller = "Home", action = "AddAndManageProperties" }
        );

        routes.MapRoute(
            name: "SubCategoryIdOnly",
            url: "{controller}/{action}/SubCategoryId-{SubCategoryId}",
            defaults: new { controller = "Home", action = "AddAndManageProperties" }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

NOTE: Stephen's answer is also a good alternative to this approach if your parameters are required to be passed in the URL. IMO, it makes more sense to use required parameters if your action method requires both of them in order to function.

But by far the simplest option is to simply use the query string. The parameters can naturally be optional and appended in any order if you do it that way, and you don't need anything more than your Default route.

Community
  • 1
  • 1
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • Thank you so much :) I just saw your answer right now.. it's working too. God bless you :) – Lucia Jun 25 '16 at 13:03