I am trying to ensure that all URLs used to access my ASP.NET MVC site are lower case. In the event that an upper case letter is in the URL, I'm changing the status code to 301 and changing the location to the lowercase version of the URL with this code:
protected void Application_BeginRequest(object sender, EventArgs e)
{
var url = Request.Url.ToString();
if (Regex.IsMatch(url, @"[A-Z]"))
{
Response.Clear();
Response.Status = "301 Moved Permanently";
Response.StatusCode = (int)HttpStatusCode.MovedPermanently;
Response.AddHeader("Location", url.ToLower());
Response.End();
}
}
However, recently a co-worker was trying to POST a form to a URL with a capital letter (forgetting about the redirect), but the action (marked with an HttpPost attribute) was not being hit. Looking at the requests in Firebug showed the original POST, but then it returned 301 and issued a GET to the lower case version.
I'm guessing the best solution is to just make sure all POSTs are to the lowercase version of the URL, but I came here to see if there is another way to handle this issue
You can create an extension method for routing that will render all url's lowercase:
The Code:
Your Route:
Now when you use the ...Html.BeginForm()... it will render a lowercase URL for the action. This will also always render lowercase urls whenever you use routing to render a link, i.e. Url.Action(); <%:Html.RenderAction() %>
By my understanding, there is no way to force a user to reissue a POST request. You can only redirect them, and doing that only specifies a URL (not POST data).
The bigger question to me is: why you are so adamant about not having uppercase URL's? HTTP specifies that URLS are case insensitive.
As Giuseppe pointed out, search engines don't index POST pages. I ended up with this:
Expanding on @bingles great answer, perhaps you do not want to force GET data to lowercase? Then you would want to use the regular expression
(?<=^[^?]*)[A-Z]
instead:Regex taken from this other answer: regex to match all uppercase letters before the first question mark
Here's a version based on scottm's solution that works with .NET 4.0