2

I have these route definitions:

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

            routes.MapRoute(
                name: "InboxToCompose",
                url: "Asistencia/Mensajeria/Componer/{origen}",
                defaults: new { controller = "Mensajeria", action = "Componer", area = "Asistencia" }
            );

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

Route "InboxToCompose" should map to this method:

    // GET: /Asistencia/Mensajeria/Componer/origen
    public ActionResult Componer(string origen)
    {

    }

This method is placed in "Mensajeria" controller in "Asistencia" area.

When I call this in view:

Url.Action("Componer", "Mensajeria", new { area = "Asistencia", origen = "Inbox" })

Generated URL is

/Asistencia/Mensajeria/Componer?origen=Inbox

That way, I can see that "origen" parameter is populated with value "Inbox" when the method is called.

However, I want it to be just

/Asistencia/Mensajeria/Componer/Inbox

If I use that URL in browser, the method is called, but with "origen" parameter equal to null.

Any advice on this, please?

jstuardo
  • 3,901
  • 14
  • 61
  • 136
  • If you have areas, you need to register then in your `RouteConfig` file. Refer [this question/answer](https://stackoverflow.com/questions/13454699/how-to-register-areas-for-routing) for an example –  Aug 23 '17 at 21:41

3 Answers3

0

Please try below in route config

routes.MapRoute(
            name: "InboxToCompose",
            url: "Asistencia/Mensajeria/Componer/{origen}",
            defaults: new { controller = "Mensajeria", action = "Componer", area = "Asistencia" , origen = ""}
        );
karthik kasubha
  • 392
  • 2
  • 13
  • No success... parameter is passed with the "?". – jstuardo Aug 23 '17 at 21:26
  • I have tried with attribute routing, adding the attribute and calling routes.MapMvcAttributeRoutes(); while registering routes. In thise case, a 404 is shown with both Asistencia/Mensajeria/Componer and Asistencia/Mensajeria/Componer/Inbox – jstuardo Aug 23 '17 at 21:42
0

Have you tried Url.RouteUrl? Instead of passing the action and controller, you pass the name of your custom route as defined in RegisterRoutes. Replace the Url.Action line with this,

Url.RouteUrl("InboxToCompose", new { area = "Asistencia", origen = "Inbox" })
Chris Gong
  • 8,031
  • 4
  • 30
  • 51
0

After a lot of tries and errors, I have found the solution.

The fact is that since this controller belongs to an area, the route should be defined in AreaRegistration derived class.

I have found that this class contains this:

public override void RegisterArea(AreaRegistrationContext context) 
{
    context.MapRoute(
        "Asistencia_default",
        "Asistencia/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
    );
}

So I moved my custom MapRoute from RouteConfig to AsistenciaAreaRegistration class. That way it worked. Both the URL generation using Url.Action and the parameter is received correctly.

I realized of this, after reading this page: https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/

That page told about attribute routing, so I tried to add an atribute to my action, but, when I called AreaRegistration.RegisterAllAreas();, a run time exception was thrown, telling that the area is already defined in AsistenciaAreaRegistration class.

So I decided to move the MapRoute to there as a logical deduction.

I prefer to add routes this way instead of attribute routing since in this way, I have all routings together, so it is easier to maintain in the future.

Regards

Jaime

jstuardo
  • 3,901
  • 14
  • 61
  • 136