zoukankan      html  css  js  c++  java
  • 在ASP.NET 2.0中实现URL重写

    URL重写技术在今天已不是什么新鲜的话题了,在Apache服务器提供了名为mod_rewrite的URL重写模块,而在IIS服务器上,也有很多商业的ISAPI 筛选器模块可供使用。然而这对于我们,没有很多的资金或使用的共享服务器,使得以上的方法都不是最佳的解决方案。幸而ASP.NET给我们提供了强大的可扩展性,能让我们自己定义页面的访问规则,很方便实现URL重写。

    在ASP.NET中实现URL重写,需要创建HTTP模块(HttpModule)或HTTP处理程序(HttpHandler),通过调用HttpContext的RewritePath方法来近进行URL重写。本篇文章使用的是HTTP模块做的示例。

    使用HTTP模块执行URL重写

    首先需要定义一个实现了IHttpModule接口的类。IHttpModule接口定义了两个方法需要实现:

    • Init(HttpApplication)。此方法在初始化HTTP模块后触发。在此方法中,您将把事件处理程序绑定到相应的HttpApplication事件。
    • Dispose()。当请求已完成并已发送回IIS时调用此方法。您应当在此处执行所有最终的清除操作。
    C#代码
    1. public virtual void Init(HttpApplication app)   
    2. {   
    3.     // WARNING!  This does not work with Windows authentication!   
    4.     // If you are using Windows authentication, change to app.BeginRequest   
    5.     app.AuthorizeRequest += new EventHandler(this.URLRewriter);   
    6. }  

    注意如果要使用窗体身份验证而不使用Windows身份验证,请将URL重写放在AuthorizeRequest事件处理程序中执行。如果要使用Windows身份验证,请在BeginRequest或AuthenticateRequest事件进行过程中安排URL重写。

    在URLRewriter方法里的第7行从配置文件里读取URL重写信息,进行处理,如对正则表达式的处理。如您对如何扩展标准的配置文件还不清楚,请看这篇Blog:扩展.NET 2.0标准配置文件

    C#代码
    1. protected void URLRewriter(object sender, EventArgs e)   
    2. {   
    3.     HttpApplication app = (HttpApplication)sender;   
    4.     string requestedPath = app.Request.Path;   
    5.     // get the configuration rules   
    6.     UrlsCollection rules = UrlsConfig.GetConfig().Urls;   
    7.     for (int i = 0; i < rules.Count; i++)   
    8.     {   
    9.         // get the pattern to look for, and Resolve the Url (convert ~ into the appropriate directory)   
    10.         string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].VirtualUrl) + "$";   
    11.         Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);   
    12.         if (re.IsMatch(requestedPath))   
    13.         {   
    14.             string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].DestinationUrl));   
    15.             RewriterUtils.RewriteUrl(app.Context, sendToUrl);   
    16.             break;   
    17.         }   
    18.     }   
    19. }  

    如果匹配,则调用RewriteUrl方法,将URL分解成路径和查询字符串两部分,以调用HttpContext.RewritePath方法来实现URL的重写。其中对“URL资源的附加路径信息”(如:Http://www.microsoft.com/virdir/page.html/tail 的tail部分)未做处理,直接用String.Empty来表示,如您需要,可以自行扩展一下。

    OK,到此为止,一个简单的URL重写程序就初步完成了,但还没有大功告成,还有一个细节的问题需要我们处理一下,就是页面回发后又会在地址栏显示出重写前的地址,也就是真实的地址,影响美观:)。有两种方法可以解决这个问题:

    • 自定义一个继承form控件的控件

     

    C#代码
    1. public class Form : System.Web.UI.HtmlControls.HtmlForm   
    2. {   
    3.     /// <summary>   
    4.     /// The RenderAttributes method adds the attributes to the rendered <form> tag   
    5.     /// We override this method so that the action attribute is not emitted.   
    6.     /// </summary>   
    7.     protected override void RenderAttributes(HtmlTextWriter writer)   
    8.     {   
    9.         // write the form's name   
    10.         writer.WriteAttribute("name"this.Name);   
    11.         base.Attributes.Remove("name");   
    12.   
    13.         // write the form's method   
    14.         writer.WriteAttribute("method"this.Method);   
    15.         base.Attributes.Remove("method");   
    16.   
    17.         // remove the action attribute   
    18.         base.Attributes.Remove("action");   
    19.   
    20.         // finally write all other attributes   
    21.         this.Attributes.Render(writer);   
    22.   
    23.         if (base.ID != null)   
    24.             writer.WriteAttribute("id"base.ClientID);   
    25.     }   
    26. }  

     

    这个方法直接去掉了form的action属性,所以页面就直接回发给自己了,能够解决问题,但使用起来比较麻烦。想象一下在每个需要重写URL的页面都要去改写form标记,够崩溃的了。

    • 利用ASP.NET 2.0控件适配器扩展架构来定制控件的输出

    在ASP.NET 2.0中,有个比较干净的诀窍可以用来重写<form>控件的action属性。具体地来说,利用新的ASP.NET 2.0控件适配器扩展架构来定制控件的输出,用提供的值来覆盖action属性的值。这不要求在.aspx页面里做任何编码改动,而只要在/app_browsers文件夹里添加一个.browser文件,注册使用一个控件适配类即可输出新的action属性。

    .browser文件 

    XML/HTML代码
    1. <browsers>  
    2.   <browser refID="Default">  
    3.     <controlAdapters>  
    4.       <adapter controlType="System.Web.UI.HtmlControls.HtmlForm"  
    5.           adapterType="URLRewriter.Form.FormRewriterControlAdapter" />  
    6.     </controlAdapters>  
    7.   </browser>  
    8. </browsers>  

    URLRewriter.Form.cs文件

     

    C#代码
    1. public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter   
    2.    {   
    3.        public FormRewriterControlAdapter()   
    4.        {   
    5.        }   
    6.        protected override void Render(HtmlTextWriter writer)   
    7.        {   
    8.            base.Render(new RewriteFormHtmlTextWriter(writer));   
    9.        }   
    10.    }   
    11.    public class RewriteFormHtmlTextWriter : HtmlTextWriter   
    12.    {   
    13.        public RewriteFormHtmlTextWriter(HtmlTextWriter writer)   
    14.            : base(writer)   
    15.        {   
    16.            base.InnerWriter = writer.InnerWriter;   
    17.        }   
    18.        public RewriteFormHtmlTextWriter(System.IO.TextWriter writer)   
    19.            : base(writer)   
    20.        {   
    21.            base.InnerWriter = writer;   
    22.        }   
    23.        public override void WriteAttribute(string name, string value, bool fEncode)   
    24.        {   
    25.            //If the attribute we are writing is the "action" attribute, and we are not on a sub-control   
    26.            //then replace the value to write with the raw URL of the request - which ensures that we'll   
    27.            //preserve the PathInfo value on postback scenarios   
    28.            if (name == "action")   
    29.            {   
    30.                HttpContext context = HttpContext.Current;   
    31.                if (context.Items["ActionAlreadyWritten"] == null)   
    32.                {   
    33.                    //We will use the Request.RawUrl property within ASP.NET to retrieve the origional   
    34.                    //URL before it was re-written.   
    35.                    value = context.Request.RawUrl;   
    36.                    //Indicate that we've already rewritten the <form>'s action attribute to prevent   
    37.                    //us from rewriting a sub-control under the <form> control   
    38.                    context.Items["ActionAlreadyWritten"] = true;   
    39.                }   
    40.            }   
    41.            base.WriteAttribute(name, value, fEncode);   
    42.        }   
    43.    }  

    直接将action属性的值赋予成URL重写后的地址,简单又实惠,何乐而不为呢。

    作者:superstone

    原文地址:http://www.51aspx.com/CT/Z9UMK7ZUJXE31/

  • 相关阅读:
    iPhone的Socket编程使用开源代码之AsyncSocket
    利用 NSSortDescriptor 对 NSMutableArray 排序
    objectc NSMutableURLRequest模拟表单提交
    Asp.net读取Excel文件 2
    把aspx绑定的数据搬至aspx.cs页面中去
    Asp.net网站如何播放Flv视频
    如何使用Flash对象去显示图片
    Could not load file or assembly 'Microsoft.ReportViewer.WebForms' or 'Microsoft.ReportViewer.Common'
    动态添加HtmlGenericControl
    Could not load file or assembly 'Microsoft.ReportViewer.ProcessingObjectModel'
  • 原文地址:https://www.cnblogs.com/yamajia/p/1171032.html
Copyright © 2011-2022 走看看