5

ASP.NET MVC 2 app

I have two actions on my controller (Toons):

  1. [GET] List
  2. [POST] Add

App is running on IIS7 integration mode, so /Toons/List works fine. But when I do POST (that redirects to /Toons/List internally) it redirects (with 302 Object Moved) back to /Toons/Add.

The problem goes away if I use .aspx hack (that works in IIS6/IIS7 classic mode).

But without .aspx - GET work fine, but POST redirects me onto itself but with GET.

What am I missing?

I'm hosting with webhost4life.com and they did change IIS7 to integrated mode already.

EDIT: The code works as expected using UltiDev Cassini server.

EDIT: It turned out to be trailing-slash-in-URL issue. Somehow IIS7 doesn't route request properly if there is no slash at the end.

EDET: Explanation of the behavior
What happens is when I request (POST) /Toons/List (without trailing slash), IIS doesn't find the handler (I do not have knowledge to understand how exactly IIS does URL-to-handler mapping) and redirects the request (using 302 code) to /Toons/List/ (notice trailing slash).

A browser, according to the HTTP specification, must redirect the request using same method (POST in this case), but instead it handles 302 as if it is 303 and issues GET request for the new URL.

This is incorrect, but known behavior of most browsers.

The solution is either to use .aspx-hack to make it unambiguous for IIS how to map requests to ASP.NET handler, or configure IIS to handle everything in the virtual directory using ASP.NET handler.

Q: what is a better way to handle this?

THX-1138
  • 21,316
  • 26
  • 96
  • 160
  • What is the code for your Add action? – Mike J Jan 26 '10 at 02:05
  • return RedirectToAction("List", "Toons"); – THX-1138 Jan 26 '10 at 02:10
  • What happens if you take [GET] of the List action? – 37Stars Feb 10 '10 at 21:58
  • [GET] of the list action works fine, since IIS responds with redirect to /Toons/List/ - which is re-requested using [GET] request. – THX-1138 Feb 11 '10 at 15:49
  • HTTP doesn't support redirection to a page using POST. When you redirect somewhere, the HTTP "Location" header tells the browser where to go, and the browser makes a GET request for that page. You'll probably have to just write the code for your page to accept GET requests as well as POST requests. – Adeel Feb 12 '10 at 17:15
  • @Adeel do not modify your domain using GET request ; ) – SDReyes Feb 12 '10 at 17:38
  • 1
    RFC 2068 Note: When automatically redirecting a POST request after receiving a 302 status code, some existing HTTP/1.0 user agents will erroneously change it into a GET request. – THX-1138 Feb 12 '10 at 21:19
  • Check this [question](http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-instead-of-get) – Adeel Feb 12 '10 at 17:17
  • I just wanted to say thank you for posting this question with so much detail. WebHost4Life still has this issue with MVC3, and I'm not sure I ever would have thought that a trailing slash on my url (which I form using @Url.Action so I would have expected to be correct!) was the problem, given that my app works perfectly before I deploy it there. I was trying to figure out why on earth it was doing both a post and a get and failing with both when I wasn't even redirecting. Anyway, thanks for saving my day! – anyeone Feb 05 '14 at 16:16

1 Answers1

1

You have control over your code. change all pages that make a post without the trailing slash to post to the correct page. if its 3rd party clients, than return an exception, that they should fix the bug.

this is expected behaviour, and its not your job to recover everything that can happen. but you should give good hints (e.g. exception message, instead of a weird error or redirect.)

cRichter
  • 1,411
  • 7
  • 7
  • Yes, I can solve it that way. I use ASP.NET MVC's routing, I am trying to avoid hacking into MVC's routing to add trailing slash to URLs. Using UltiDev doesn't do it the way IIS 7 does it (i.e. with UltiDev my code works perfectly as I want it). – THX-1138 Jul 09 '10 at 14:24