Home > Net >  MVC: Using the routing attribute with a url that has an additional segment
MVC: Using the routing attribute with a url that has an additional segment

Time:03-15

I have a controller called Search. A normal url would be the following:

  • localhost:44351//Search/ByCity

This would hit my ByCity action within my SearchController.

Now however, a url such as the following example, would also need to hit an action within the SearchController:

  • localhost:44351//Search/Pharmacy/ByCity

I need to somehow tell my SearchController, if the url contains "Pharmacy/ByCity", to go to the ByCity action.

I've tried using the routing attribute, but my app still hits my old Pharmacy action instead.

In my RouteConfig, I have this:

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

Then, in my SearchController, I have this:

   public virtual ActionResult Pharmacy()
    {
        //this is an existing action, which gets hit, even when I type in "Pharmacy/ByCity", which is not what I want to happen.
    }

    [Route("Pharmacy/ByCity")]
    public virtual ActionResult ByCity()
    {
        //this never gets hit
    }

Any idea how to have a url containing "Pharmacy/ByCity" to hit my "ByCity" action, rather than "Pharmacy"?

Thanks

CodePudding user response:

Routes are accessed depending on their Order in the routing table.

For conventional routing (RouteConfig.cs), you could add your specific route before the default route.

  1. Remove your Route[] attributes in the controller
  2. Use the code below for RouteConfig
public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

   // add your specific route, before the default route
   routes.MapRoute(
      name: "SearchByCity", // random name
      url: "Search/Pharmacy/ByCity",
      defaults: new { controller = "Search", action = "ByCity" }
   );
   
   // this is the default route
   routes.MapRoute(
      name: "Default",
      url: "{controller}/{action}/{id}",
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
   );
}

If you want to use Attribute Route, follow steps below.

  1. Remove the default route in RouteConfig.
public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   routes.MapMvcAttributeRoutes();
}
  1. Then use the controller below, we used RoutePrefix for the controller, and Route for the actions.
[RoutePrefix("Search")]
public class SearchController : Controller
{
   [Route("Pharmacy")]
   public virtual ActionResult Pharmacy()
   {
      return View("index");
   }

   [Route("Pharmacy/ByCity")]
   public virtual ActionResult ByCity()
   {
      return View("index");
   }
}

CodePudding user response:

It is possible to achieve with the conventional route by set up like below:

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

routes.MapRoute(
    name: "Pharmacy",
    url: "{clientname}/{controller}/Pharmacy/{action}",
    defaults: new { controller = "search" }
);

routes.MapRoute(
    name: "Search",
    url: "{clientname}/{controller}/{action}",
    defaults: new { controller = "search", action = "Index" }
);          

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