0

I'm having an issue with url route with parameter. I followed by this link: ASP.NET MVC 5 culture in route and url

I have tag action under controller Blog. According to culture, I created two routes in route config :

routes.MapRoute(
     name: "TagWithCulture",
     url: "{culture}/{controller}/{action}/{Name}/{page}/{pageNo}",
     defaults: new { controller = "Blog", action = "Tag", Name = UrlParameter.Optional, pageNo = UrlParameter.Optional, page = UrlParameter.Optional },
     constraints: new { culture = new CultureConstraint(defaultCulture: "ar", pattern: "[a-z]{2}") }
);

routes.MapRoute(
     name: "Tag",
     url: "{controller}/{action}/{Name}/{page}/{pageNo}",
     defaults: new { controller = "Blog", action = "Tag", Name = UrlParameter.Optional, pageNo = UrlParameter.Optional, page = UrlParameter.Optional }
)

The action in controller is as this line of code to accept 2 parameters:

 public async Task<ActionResult> Tag(string Name, int? pageNo)

The problem is: when I browse url with query string like this:

localhost:1025/blog/tag?name=XYZ

and debug, I can see that 'name' parameter has a value, otherwise, by browsing url and applying route:

localhost:1025/blog/tag/XYZ

the parameter 'name' becomes null!

This is causing a headache, is there a solution for that?

Community
  • 1
  • 1
  • Are the two `MapRoute` calls above or below the default `MapRoute`? I'm wondering if it's getting mapped to the default route that has `id` as the final parameter instead of hitting these? – stephen.vakil Sep 08 '16 at 19:14
  • @stephen.vakil Both are below default MapRoute . I put it above and here what happens: It works fine but 'Tag' action becomes the homepage which I mean when you browse localhost:1025/ it shows localhost/tag without parameters and without changing the url in the browser !!! – Tamer Kamal Sep 09 '16 at 15:44
  • is that a must to make always default routeMaps to be at the top of routeMaps ?? I put the default routes on the top and still Tag action runs and accept paramaters only in query strings !!! – Tamer Kamal Sep 09 '16 at 15:48
  • It will try to match the routes to your mappings in the order you specify. So if the default route is on top, then it will try to use that first. In this case, I think it will not match the default route because you made the parameters all optional in such a way that it will match against your supplied routes when you don't want it to. I would make at least `Name` not optional perhaps? – stephen.vakil Sep 09 '16 at 15:51
  • Or specifically match against `blog/tag` instead of parameterizing it in your `url` specifications. – stephen.vakil Sep 09 '16 at 16:03
  • I tried to match against blog/tag without parametertizing controller and action ==> result is error page "I must Include Controller Name" So , here are the changes I made in RouteConfig.cs – Tamer Kamal Sep 09 '16 at 17:16
  • So , changes I made in RouteConfig.cs case 1 . I changed the parameter Name and made it TagName . Then I made it not optional by removing it from the paramter list. after that I made the default routemaps at the end of route List ==> result is that the url for tag action works fine tag/xyz (note: query string parameter stopped working) and new case fired up: localhost:1025/ shows "The resource cannot be found" . if I make default route at top, home page works.on the other hand, tag/xyz won't work @stephen.vakil – Tamer Kamal Sep 09 '16 at 17:22

1 Answers1

0

As discussed, make your specific routes be processed first by putting them above the default routes. Then, make your routes more specific so they don't inappropriately catch things not referring to blog.

I'm not sure if both page and pageNo are required -- they aren't in your action method so I assume not.

routes.MapRoute(
   name: "Tag",
   url: "blog/tag/{Name}/{pageNo}",
   defaults: new { controller = "Blog", action = "Tag", pageNo = UrlParameter.Optional }
);

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

Doing it the way you did it in your question does not work as intended, because going to / will try to map to the blog/tag action.

stephen.vakil
  • 3,492
  • 1
  • 18
  • 23