使用URL Rewrite和404.aspx时回发问题

时间:2009-01-04 15:47:19

标签: asp.net url-rewriting postback http-status-code-404

我在我的网站上使用网址重写来获取以下网址: http://mysite.com/users/john
而不是 http://mysite.com/index.aspx?user=john

要使用IIS6实现此无扩展名重写并且无法访问托管服务器,我使用“404-approach”。当服务器找不到请求时,执行映射的404页面,因为这是一个aspx页面,可以执行重写(我可以使用托管服务上的控制面板设置404映射)。 / p>

这是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;
}

在我的主页上的Page_Load中,我在form-tag的action-attribute中设置了正确的URL。

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

重写工作正常,但是当我在页面上执行回发时,不会执行回发,这可以以某种方式解决吗?

问题似乎与404方法有关,因为当我尝试没有它(并且失去无扩展功能)时,回发有效。那是我要求的时候:
http://mysite.com/users/john.aspx

可以解决这个问题,还是有其他解决方案可以满足我的要求(IIS6,没有serveraccess / ISAPI过滤器和无扩展名)。

7 个答案:

答案 0 :(得分:9)

form1.Action = Request.RawUrl

结合使用
HttpContext.Current.RewritePath("/Default.aspx", true); 

对我来说非常好。

设置表单Action属性是我丢失的那个......

感谢您的解决方案!!!

答案 1 :(得分:4)

Scott Guthrie介绍了在没有IIS访问的情况下执行此操作的不同方法:

http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx

就个人而言,我过去创建了HTTPModules,它很容易组合在一起。

答案 2 :(得分:3)

form1.Action = Request.RawUrl也是如何用C#编写的把它放在页面加载方法中

答案 3 :(得分:1)

我首先安装Live Http Headers,然后看看Http请求是什么。

啊,在那篇文章中它解释了它,看起来像form标签的action属性是错误的:

  

人们在使用ASP.NET和Url-Rewriting时经常遇到的问题与处理回发方案有关。具体来说,当您在页面上放置<form runat="server">控件时,ASP.NET将自动默认输出标记的“action”属性以指向它所在的页面。使用URL重写时的问题是控件呈现的URL不是请求的原始URL(例如:/ products / books),而是重写的URL(例如:/products.aspx?category =书籍)。这意味着当您对服务器进行回发时,URL将不是您干净利落的URL。

     

使用ASP.NET 1.0和1.1,人们经常使用<form>控件进行子类化并创建自己的控件,以正确输出要使用的操作。虽然这有效,但它最终会有点混乱 - 因为这意味着你必须更新所有页面才能使用这个备用表单控件,并且它有时会遇到Visual Studio WYSIWYG设计器的问题。

     

好消息是,使用ASP.NET 2.0,您可以使用更清晰的技巧重写<form>控件上的“action”属性。具体来说,您可以利用新的ASP.NET 2.0控制适配器可扩展性体系结构来自定义<form>控件的呈现,并使用您提供的值覆盖其“action”属性值。这不需要您更改.aspx页面中的任何代码。相反,只需将.browser文件添加到/ app_browsers文件夹中,该文件夹注册一个Control Adapter类,用于输出新的“action”属性......

答案 4 :(得分:1)

您可以使用以下代码:

form1.Action = Request.RawUrl

我不确定在C#中会有什么,但这就是它在VB中的作用并且可以实现一种处理

答案 5 :(得分:1)

尝试这样的事情:

            if (Request.HttpMethod == "GET" && shouldChangeUrl)
            {
                urlRedirect = "REAL-URL-HERE";

                _postBackUrl = urlRedirect;
                Context.RewritePath(urlRedirect);
            }
            else
                //If Post Back (Request.HttpMethod="POST")
                Context.RewritePath(_postBackUrl);

因此,在重写url时,将回发的实际URL保存在变量(此处为:_postBackUrl)中,然后仅在回发时使用它。

答案 6 :(得分:0)

问题在于404处理。您的表单发布到一个不存在的页面,ASP.NET将请求重定向到404页面,因此它丢失了所有的回发数据。

唯一的解决方案是将表单的action属性设置为现有页面,以便用户在提交表单时看到index.aspx?user = john。对于搜索引擎优化,这不会是一个问题,因为爬虫不发布帖子,因此看不到丑陋的地址。