Postback problem when using URL Rewrite and 404.as

2019-05-15 00:56发布

I'm using URL rewrite on my site to get URLs like:
http://mysite.com/users/john
instead of
http://mysite.com/index.aspx?user=john

To achive this extensionless rewrite with IIS6 and no access to the hosting-server I use the "404-approach". When a request that the server can't find, the mapped 404-page is executed, since this is a aspx-page the rewrite can be performed (I can setup the 404-mapping using the controlpanel on the hosting-service).

This is the code in Global.asax:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    string url = HttpContext.Current.Request.Url.AbsolutePath;
    if (url.Contains("404.aspx"))
    {
        string[] urlInfo404 = Request.Url.Query.ToString().Split(';');
        if (urlInfo404.Length > 1)
        {
            string requestURL = urlInfo404[1];
            if (requestURL.Contains("/users/"))
            {
                HttpContext.Current.RewritePath("~/index.aspx?user=" + GetPageID(requestURL));              
                StoreRequestURL(requestURL);
            }
            else if (requestURL.Contains("/picture/"))
            {
                HttpContext.Current.RewritePath("~/showPicture.aspx?pictureID=" + GetPageID(requestURL));
                StoreRequestURL(requestURL);
            }
        }
    }
}

private void StoreRequestURL(string url)
{
    url = url.Replace("http://", "");
    url = url.Substring(url.IndexOf("/"));
    HttpContext.Current.Items["VirtualUrl"] = url;
}

private string GetPageID(string requestURL)
{
    int idx = requestURL.LastIndexOf("/");
    string id = requestURL.Substring(idx + 1);
    id = id.Replace(".aspx", ""); //Only needed when testing without the 404-approach
    return id;
}

And in Page_Load on my masterpage I set the correct URL in the action-attribute on the form-tag.

protected void Page_Load(object sender, EventArgs e)
{
    string virtualURL = (string)HttpContext.Current.Items["VirtualUrl"];
    if (!String.IsNullOrEmpty(virtualURL))
    {
        form1.Action = virtualURL;
    }
}

The rewrite works fine but when I perform a postback on the page the postback isn't executed, can this be solved somehow?

The problem seems to be with the 404-approach because when I try without it (and loses the extensionless-feature) the postback works. That is when I request:
http://mysite.com/users/john.aspx

Can this be solved or is there any other solution that fulfil my requirements (IIS6, no serveraccess/ISAPI-filter and extensionless).

7条回答
家丑人穷心不美
2楼-- · 2019-05-15 01:22

I would start by installing Live Http Headers and see whats going on with the Http requests.

Ahh here in that article it explains it, looks like the action attribute of the form tag is wrong:

One gotcha that people often run into when using ASP.NET and Url-Rewriting has to-do with handling postback scenarios. Specifically, when you place a <form runat="server"> control on a page, ASP.NET will automatically by default output the "action" attribute of the markup to point back to the page it is on. The problem when using URL-Rewriting is that the URL that the control renders is not the original URL of the request (for example: /products/books), but rather the re-written one (for example: /products.aspx?category=books). This means that when you do a postback to the server, the URL will not be your nice clean one.

With ASP.NET 1.0 and 1.1, people often resorted to sub-classing the <form> control and created their own control that correctly output the action to use. While this works, it ends up being a little messy - since it means you have to update all of your pages to use this alternate form control, and it can sometimes have problems with the Visual Studio WYSIWYG designer.

The good news is that with ASP.NET 2.0, there is a cleaner trick that you can use to rewrite the "action" attribute on the <form> control. Specifically, you can take advantage of the new ASP.NET 2.0 Control Adapter extensibility architecture to customize the rendering of the <form> control, and override its "action" attribute value with a value you provide. This doesn't require you to change any code in your .aspx pages. Instead, just add a .browser file to your /app_browsers folder that registers a Control Adapter class to use to output the new "action" attribute...

查看更多
登录 后发表回答