URL重写 时遇到的问题

来源:互联网 发布:java全局变量命名规则 编辑:程序博客网 时间:2024/05/16 19:30

使用微软提供的url重写组件urlrewirter可以很轻松的实现URL重写,方法简单如下:

  1. 下载urlwriter组件:http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx,将该组件方到web application的bin文件夹下。
  2. 配置web.config文件:
    <?xml version="1.0" encoding="utf-8" ?> 
    <configuration> 
        
    <configSections> 
            
    <section name="RewriterConfig"type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" /> 
        
    </configSections> 
        
    <RewriterConfig> 
            
    <Rules> 
                
    <RewriterRule> 
                    
    <LookFor>~/d(d+).aspx</LookFor> 
                    
    <SendTo>~/default.aspx?id=$1</SendTo> 
                
    </RewriterRule> 
            
    </Rules> 
        
    </RewriterConfig> 
        
    <system.web> 
            
    <httpHandlers> 
                
    <add verb="*" path="*.aspx" type="URLRewriter.RewriterFactoryHandler, URLRewriter" /> 
            
    </httpHandlers> 
        
    </system.web> 
    </configuration> 

其中<section name="RewriterConfig"type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" /> 
是表示config文件中配置节RewriterConfig的处理程序URLRewriter.Config.RewriterConfigSerializerSectionHandler,该处理程序在程序集URLRewriter中.配置节UrlRewriterConfig配置节就是请求的URL和实际URL的映射,且支持正则表达式,使用更方便。

但是会遇到这样的问题:当你请求一个URL(如:http://localhost/guangboo/d23.aspx)时, 会被重放到http://localhost/guangboo/default.aspx?id=23 去,但是在该页面点击某一按钮或触发回发事件时候,页面就会被回发到http://localhost/guangboo/default.aspx?id=23 页面,这样实际的URL还是被暴露了,就失去了URL重写的意义了,当我们用记事本打开查看http://localhost/guangboo/d23.aspx页面时,我们会发现,form的action属性是default.aspx,这就是原因所在,网上有这样两种方法可以解决这样的问题,也都是从form 的action属性为出发点的:

1,自己定义一个Actionlessform类,在aspx中不再使用系统提供的form 标记

namespace ActionlessForm  

    
public class
 Form : System.Web.UI.HtmlControls.HtmlForm 
    

        
protected override void
 RenderAttributes(HtmlTextWriter writer) 
        

            writer.WriteAttribute(
"name"this
.Name); 
            
base.Attributes.Remove("name"
); 
            writer.WriteAttribute(
"method"this
.Method); 
            
base.Attributes.Remove("method"
); 
            
this
.Attributes.Render(writer); 
            
base.Attributes.Remove("action"
); 
            
if (base.ID != null

                writer.WriteAttribute(
"id"base
.ClientID); 
         }
 
    }
 
}
 

做用法法是在 ASP.NET 网页的顶部添加以下内容: <%@ Register TagPrefix="skm" Namespace="ActionlessForm" Assembly="ActionlessForm" %> 然后,<form runat="server">(如果有)替换为:<skm:Form id="Form1" method="post" runat="server"> 
并将右边的 </form> 标记替换为:</skm:Form>

(2)第二种方法就是继承page,这样你不需要在aspx页中改任何东西。
代码

  public class OLPage : Page {
        
public OLPage() { }

        
protected override void Render(HtmlTextWriter writer) {
            
if (writer is System.Web.UI.Html32TextWriter) 
{
                writer 
= new
 FormFixerHtml32TextWriter(writer.InnerWriter);
            }
 else {
                writer 
= new
 FormFixerHtmlTextWriter(writer.InnerWriter);
            }

            
base.Render(writer);
        }

    }


    
internal class FormFixerHtml32TextWriter : System.Web.UI.Html32TextWriter {
        
private string _url; // 假的URL

        internal FormFixerHtml32TextWriter(TextWriter writer)
            : 
base(writer) 
{
            _url 
=
 HttpContext.Current.Request.RawUrl;
        }

        
public override void WriteAttribute(string name, string value, bool encode) {
            
if (_url != null && string.Compare(name, "action"true== 0
{
                value 
=
 _url;
            }

            
base.WriteAttribute(name, value, encode);
        }

    }

    
internal class FormFixerHtmlTextWriter : System.Web.UI.HtmlTextWriter {
        
private string
 _url;
        
internal
 FormFixerHtmlTextWriter(TextWriter writer)
            : 
base(writer) 
{
            _url 
=
 HttpContext.Current.Request.RawUrl;
        }

        
public override void WriteAttribute(string name, string value, bool encode) {
            
if (_url != null && string.Compare(name, "action"true== 0
{
                value 
=
 _url;
            }

            
base.WriteAttribute(name, value, encode);
        }

    }

然后把项目中的所有aspx文件对应的cs文件中的继承page类的代码改写为继承OLPage。
例如
public class WebForm1:page
改写为
public class WebForm1:OLPage即可。

但是,我想用http://localhost/guangboo/?a=23 重写到http://localhost/guangboo/Article.aspx?cc=23 的时候又出现问题了,如果用上面的方法来实现这个的话,当在http://localhost/guangboo/?a=23页面产生回发事件时,就会重发到http://localhost/guangboo/default.aspx?a=23;因为默认/?代表了/default.aspx?就是请求http://locahost/guangboo/  时候就是请求http://localhost/guangboo/default.aspx 一样。同样用记事本打开http://localhost/guangboo/?a=23 可以看到form 的action属性是default.aspx?a=23,只要对上面的OLPage 类稍加修改就可以到目的了,即将OLPage类中的HttpContext.Current.Request.RawUrl改为HttpContext.Current.Request.RawUrl.Replace("default.aspx","");即可。也就是把action中的default.aspx去掉。

改好后,运行又来了一个问题,网页什么内容都没了,除了EnableViewState="true"的控件内容外。将控件的EnableViewState属性设为true ,OK!

注意:我们知道EnableViewState属性用用来保存控件的信息的,在HTML文件中表现为一个<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTIwMDIzMDY0MjcPZBYCZg9kFgICAw9kFgYCBQ8WAh4LX......"/>的隐藏元素,EnableViewState会使页面的大小膨胀很多。因此期待更好的方法。

原创粉丝点击