0

I have the following controller:

    public class MyController : BaseController
    {
        public ActionResult Index(string id) { /* Code */ }

        public ActionResult MyAjaxCall(string someParameter) { /* Code */ }
    }

I have also added the following in the RouteConfig.cs

    routes.MapRoute(
        name: "MyController",
        url: "MyController/{id}",
        defaults: new { controller = "MyController", action = "Index" }
    )

So my idea is to be able to go directly to the index action using this url /MyController/{Id}, and that seems to work.

However when on the Index page I need to make an Ajax call to /MyController/MyAjaxCall/{someParameter}. However this url is pointing to the Index controller, and is interpreting MyAjaxCall as the id in the Index action.

Any ideas how I can exclude this action from following the newly added route config setting?

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
JEPAAB
  • 166
  • 3
  • 14
  • 1
    Include an additional route with `url: "MyController/MyAjaxCall/{someParameter}"` and `defaults: new { controller = "MyController", action = "MyAjaxCall" }` –  Jul 10 '16 at 06:49

2 Answers2

4

If that your id can only be integer number, you can add a constraint to your id field, which specifies that your id can only be numbers:

routes.MapRoute(
    name: "MyController",
    url: "MyController/{id}",
    defaults: new { controller = "MyController", action = "Index" },
    constraints: new { id = @"\d+" }  // <- constraints of your parameters
)

Here you can use any regular expression that works for your business logic.

Also make sure to register this route before your default route registration, in that case MVC will first try to match this route, and only if it doesn't match it will try to match the default route.

dotnetom
  • 24,551
  • 9
  • 51
  • 54
  • So when the constraints are not met, will the URL be routed using the default route? – JEPAAB Jul 10 '16 at 06:54
  • @JEPAAB Yes, if constraints are not matched, then the route is considered not matched – dotnetom Jul 10 '16 at 06:54
  • However in my case I need the parameter to be as string. Is it possible to add a constraint to exclude the 'MyAjaxCall' parameter? – JEPAAB Jul 10 '16 at 06:56
  • @JEPAAB You can use any regular expression. So if you define regular expression which matches any text except for 'MyAjaxCall' then this will work. Here is the sample how to write regular expression http://stackoverflow.com/a/14147470, though I haven't tested this – dotnetom Jul 10 '16 at 07:00
2

It sounds like you have the routes in the wrong order. When using MVC routing, the first match always wins, so you must place the most specific routes first before general routes.

routes.MapRoute(
    name: "MyControllerAJAX",
    url: "MyController/MyAjaxCall/{someParameter}",
    defaults: new { controller = "MyController", action = "MyAjaxCall" }
)

routes.MapRoute(
    name: "MyController",
    url: "MyController/{id}",
    defaults: new { controller = "MyController", action = "Index" }
)

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Community
  • 1
  • 1
NightOwl888
  • 55,572
  • 24
  • 139
  • 212