6

I have a controller called HotelsController to insert and edit hotels.

It has the following setup (method implementation removed for simplicity):

[RoutePrefix("{member_id:int}/hotels")]
public class HotelsController : ApplicationController
{
    [Route("delete/{id:int}", Name = NamedRoutes.HotelDelete)]
    public ActionResult Delete(int id)
    {
    }

    [Route("new", Name = NamedRoutes.HotelNew)]
    public ActionResult New()
    {
    }

    [HttpPost]
    [ValidateInput(false)]
    public ActionResult New(HotelDataEntry hotel)
    {
    }

    [Route("edit/{id:int}", Name = NamedRoutes.HotelEdit)]
    public ActionResult Edit(int id)
    {
    }

    [HttpPost]
    [ValidateInput(false)]
    public ActionResult Edit(HotelDataEntry hotel)
    {
    }
}

As you can see the following routes are using attribute routing:

  • Delete
  • New (without parameters)
  • Edit (without parameters)

The following routes use no attribute routing:

  • New (with parameters)
  • Edit (with parameters)

The routing is setup in Global.asax.cs as follows:

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

        routes.MapMvcAttributeRoutes();

        routes.MapRoute(
            Routen.Standard.ToString(),
            "{member_id}/{controller}/{action}/{id}",
            new { action = "browse", id = UrlParameter.Optional },
            new { id = AllowedIdsRegExOptional }
        );
    }

Problem: Attribute routing works. I can call the Edit action with http://localhost:54868/301011/hotels/edit but the form on that page should post to the same uri and call the action that uses no attribute routing. But instead the action using the attribute based routing is called again. Why?

The form is supplied with method="post". Do you have any idea why the convention based route is not used? Thank you for your help.

Edit: I tried to add [HttpGet] in front of the attribute-routed New and Edit actions. The result is that on posting the form ASP.NET shows an error that the route is invalid. So for some reasons, the convention based routing is not working on the controller.

Krisztián Balla
  • 19,223
  • 13
  • 68
  • 84

1 Answers1

0

It seems that you cannot use both (attribute-based and convention-based) routing techniques in the same controller.

So what I did to resolve the issue is to add attribute-based routes to the two "unreachable" action methods. The route of these methods is the same as the route of the actions with the same name, but the name of the route is different (since route-names must be unique).

[RoutePrefix("{member_id:int}/hotels")]
public class HotelsController : ApplicationController
{
    [Route("delete/{id:int}", Name = NamedRoutes.HotelDelete)]
    public ActionResult Delete(int id)
    {
    }

    [Route("new", Name = NamedRoutes.HotelNew)]
    public ActionResult New()
    {
    }

    [HttpPost]
    [ValidateInput(false)]
    [Route("new", Name = NamedRoutes.HotelNewPost)]
    public ActionResult New(HotelDataEntry hotel)
    {
    }

    [Route("edit/{id:int}", Name = NamedRoutes.HotelEdit)]
    public ActionResult Edit(int id)
    {
    }

    [HttpPost]
    [ValidateInput(false)]
    [Route("edit/{id:int}", Name = NamedRoutes.HotelEditPost)]
    public ActionResult Edit(HotelDataEntry hotel)
    {
    }
}
Dale K
  • 25,246
  • 15
  • 42
  • 71
Krisztián Balla
  • 19,223
  • 13
  • 68
  • 84
  • I have opened a similar but slightly different question recently ( http://stackoverflow.com/questions/28075503/routingattribute-mixed-with-routingcollection-extended-with-routinghandlers). Prior to that judging by this http://forums.asp.net/t/1572555.aspx?Url+RouteUrl+Generates+bad+urls+with+collection+property and this http://erraticdev.blogspot.com/2011/03/removing-route-values-from-linksurls-in.html the issue can be solved by extending/rewriting System.Web.Routing.ParsedRoute.Bind(). As I'm new to the "decoupled" MVC architecture can you provide some directions ? where to look next? – Ion Ciobanu Jan 21 '15 at 19:46
  • Unfortunately I have only very basic knowledge about the routing mechanisms. I'm affraid I can't help you out there. – Krisztián Balla Jan 22 '15 at 08:13