Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I would like to leave out the action in url as I do not consider that to be a restful approach. Default routes should be:

"{controller}/{id}"

And then call the action that corresponds to the HTTP method used. For example I am decorating a PUT action like thus:

[HttpPut]
public ActionResult Change()
{
    return View();
}

However when cUrl-ing this, I get a 404. So I'm doing something wrong, any one tried this approach before?

I'm using the MVC4 beta.

This is all I'm doing to set up the Routes:

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{id}",
        defaults: new { controller = "Home", action = "Index", id = RouteParameter.Optional }
    );
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
87 views
Welcome To Ask or Share your Answers For Others

1 Answer

[HttpPut]
[ActionName("Index")]
public ActionResult Change()
{
    return View();
}

The action method selector in MVC will only allow you to have at most, 2 action method overloads for the same-named method. I understand where you are coming from with wanting to only have {controller}/{id} for the URL path, but you may be going about it in the wrong way.

If you only have 2 action methods for your controller, say 1 for GET and 1 for PUT, then you can just name both of your actions Index, either like I did above, or like this:

[HttpPut]
public ActionResult Index()
{
    return View();
}

If you have more than 2 methods on the controller, you can just create new custom routes for the other actions. Your controller can look like this:

[HttpPut]
public ActionResult Put()
{
    return View();
}

[HttpPost]
public ActionResult Post()
{
    return View();
}

[HttpGet]
public ActionResult Get()
{
    return View();
}

[HttpDelete]
public ActionResult Delete()
{
    return View();
}

... if your global.asax looks like this:

routes.MapRoute(null,
  "{controller}/{id}", // URL with parameters
  new { controller = "Home", action = "Get", id = UrlParameter.Optional },
  new { httpMethod = new HttpMethodConstraint("GET") }
);

routes.MapRoute(null,
  "{controller}/{id}", // URL with parameters
  new { controller = "Home", action = "Put", id = UrlParameter.Optional },
  new { httpMethod = new HttpMethodConstraint("PUT") }
);

routes.MapRoute(null,
  "{controller}", // URL with parameters
  new { controller = "Home", action = "Post", id = UrlParameter.Optional },
  new { httpMethod = new HttpMethodConstraint("POST") }
);

routes.MapRoute(null,
  "{controller}/{id}", // URL with parameters
  new { controller = "Home", action = "Delete", id = UrlParameter.Optional },
  new { httpMethod = new HttpMethodConstraint("DELETE") }
);

routes.MapRoute(
  "Default", // Route name
  "{controller}/{id}", // URL with parameters
  new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

... these new 4 routes all have the same URL pattern, with the exception of the POST (since you should POST to the collection, yet PUT to the specific id). However, the different HttpMethodConstraints tell MVC routing only to match the route when the httpMethod corresponds. So when someone sends DELETE to /MyItems/6, MVC will not match the first 3 routes, but will match the 4th. Similarly, if someone sends a PUT to /MyItems/13, MVC will not match the first 2 routes, but will match the 3rd.

Once MVC matches the route, it will use the default action for that route definition. So when someone sends a DELETE, it will map to the Delete method on your controller.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...