简体   繁体   中英

Is it possible to use attribute routing and convention based routing in the same controller?

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.

It seems that you cannot use both (attribute-based and conventino-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)
    {
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM