I recently used HttpContext.RewritePath in my global.asx page in asp.net 4.0. The url rewrite worked fine but the was a caveat, when i try to submit the form i got error 404. I realized that the action property of my form was not pointing to the correct url (the most common problem with RewritePath method). So I came up with the following work around. Hope this could help someone who experiencing the same problem.
my first work around... create a method that finds the current page including querystring. Once the page is found stick it into the form action. You can use the page PreRender event for that. Example
''' <summary>
''' Gets this page name
''' </summary>
''' <returns>Current Working Page Url</returns>
Protected Function GetCurrentUrl(ByVal includingQstring As Boolean) As String
Dim Url As String = String.Empty
If HttpContext.Current Is Nothing Then
Return Url
End If
If includingQstring Then
Dim host As String = ResolveHost(False)
If host.EndsWith("/") Then
host = host.Substring(0, host.Length - 1)
End If
Url = host + HttpContext.Current.Request.RawUrl
Else
Url = HttpContext.Current.Request.Url.GetLeftPart(UriPar tial.Path)
End If
Return Url
End Function
''' <summary>
''' Resolves the host location
''' </summary>
''' <param name="secured">Use secure socket layer; true/false</param>
''' <returns>Store host location</returns>
Protected Function ResolveHost(ByVal secured As Boolean) As String
Dim retval As String = "http://" & ServerVariables("HTTP_HOST")
Dim prefx = "http://www."
If Not retval.Contains(www) Then
If Not HttpContext.Current.Request.Url.IsLoopback Then
retval = retval.Replace("http://", prefx)
secured = False
End If
End If
If secured Then
If Not OwnSSL Then
retval = SharedSSL
Else
retval = retval.Replace("http:/", "https:/")
End If
Else
retval = retval.Replace("www.www", "www")
If Not retval.EndsWith("/") Then
retval = retval & "/"
End If
Return retval
End Function
Now that we've got this function, in the page prerender add the following:
Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
form1.Action = Me.GetCurrentUrl(True)
MyBase.OnPreRender(e)
End Sub
That's it for the first workaround!
Workaround 2:
First we need to create a custom form that inherits from HtmlForm Class
NameSpace RewriteFormWorkaround
Public Class MyCustomForm
Inherits System.Web.UI.HtmlControls.HtmlForm
Protected Overrides Sub RenderAttributes(ByVal writer As HtmlTextWriter)
Attributes.Add("action", GetCurrentUrl(True))
Attributes.Add("id", "myform")
Attributes.Add("method", "Post")
Attributes.Render(writer)
End Sub
End NameSpace
Add the following directive to your page :
<%@Register TagPrefix="cf" NameSpace="RewriteFormWorkaround" Assembly="MyCustomForm" %>
Replace your existing form with the following:
<cf:Form runat="server" id="form1">
......
</cf:Form>
Hope this helps someone!!