• ASP.net:URL重写实现IHttpHandler接口



    转:http://www.ninedns.com/asp.net/2007102520726.html 
    以前用url重写时是用的ms urlrewriter,用了以后发现了很多不足,自定义功能太弱,而且随着重写规则的增加,web.config可能会越来越大,实际上,url重写就是实现IHttpHandler接口.

    整个流程分二步走:

    1、用一个xml文件来存储重写规则,其中这些规则是一些简单的正则表达式
    2、实现IHttpHandler接口

    首先看一下xml文件的格式:

    <?xml version="1.0" encoding="utf-8" ?>
    <root>
    <regex>
                    <!--重写以后的虚拟地址-->
    <b><![CDATA[xxx,(?<id>[0-9]+).html$]]></b>
    <!--实际地址-->
                    <a><![CDATA[xxx.aspx?id=${id}]]></a>       
    </regex>
    </root>

    相信上面的xml大家都能看懂.

    using System;
    using System.IO;
    using System.Data;
    using System.Configuration;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Text;
    using System.Text.RegularExpressions;
    using Microsoft.VisualBasic;
    //RegexInfo结构,用来存储从xml文件中读取到的数据
    public struct RegexInfo
    {
        public string _before;
        public string _after;
        public RegexInfo(string before, string after)
        {
            _before = before.ToLower();
            _after = after.ToLower();
        }
    }
    //ipFilter结构,用来存储被封的IP
    public struct ipFilter
    {
        public string _ip;
        public ipFilter(string ip)
        {
            _ip = ip;
        }
    }
    public class HtmlHttpHandler : IHttpHandler   //实现IHttpHandler接口
    {

        private List<RegexInfo> _regex_list = new List<RegexInfo>();
        private List<ipFilter> _ip_filter = new List<ipFilter>();
        public HtmlHttpHandler()
        {
            DataSet ds = new DataSet();
            //读取url重写规则文件,并写入RegexInfo结构的实例中
            ds.ReadXml(System.Web.HttpContext.Current.Server.MapPath("~/App_Data/Regexs.xml"));
            foreach (DataRow r in ds.Tables["regex"].Rows)
                _regex_list.Add(new RegexInfo(((string)r["b"]).Trim(), ((string)r["a"]).Trim()));
            ds.Reset();
            //读取被封的IP列表
            ds.ReadXml(System.Web.HttpContext.Current.Server.MapPath("~/App_Data/ipFilter.xml"));
            foreach(DataRow r in ds.Tables["IpFilters"].Rows)
                _ip_filter.Add(new ipFilter((string)r["ip"]));
        }

        public void ProcessRequest(HttpContext context)
        {
            string _ip = context.Request.UserHostAddress;   //获取IP
            foreach (ipFilter r in _ip_filter)
            {
                if (_ip == r._ip)
                {
                    context.Response.Write("对不起,您的IP:"+_ip+"已被限制!");
                    context.Response.End();
                }
            }
            string path = context.Request.Path.ToLower();   //获取当前访问的重写过的虚假URL
            foreach (RegexInfo r in _regex_list)
                path = Regex.Replace(path, r._before, r._after);      //匹配出其真实的URL
            context.Server.Execute(path);
        }

        // Override the IsReusable property.
        public bool IsReusable
        {
            get { return true; }
        }
    }

    OK,IHttpHandler接口就被实现了,下面稍配一下web.config就可以实现URL重写了
    在web.config的<system.web></system.web>中加入 :

     <httpHandlers>
          <add verb="*" path="*.html" type="HtmlHttpHandler"/>
     </httpHandlers>

    表示后缀名为.html的文件全部交给HtmlhttpHandler类去处理,最后配一下iis就行了。

    至于简繁的转换,你可以加到ProcessRequest中,至于如何实现转换见下一页。

    ASP.net的RUL重写

     

    有关于URL的重写,本文也只是拿来主意。相继有MS的组件“URLRewriter”和在Global.asax里的“Application_BeginRequest()”编码方式,以及IIS里的ISAPI设置。

    娜列下来,实现方法也都很简单。

     

    方法一:MS组件

    这里也不用详解了,相关请看:

    http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx

    用法很简单,只需要把组件URLRewriter.dll拷到应用程序的bin目录下,然后在web.config下加入如下代码:

    在<configuration></configuration>中加入:

         <configSections>

              <section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />

         </configSections>

        

         <RewriterConfig>

              <Rules>

                  <RewriterRule>

                       <LookFor>~/(\d{4})/(\d{2})/Default\.aspx</LookFor>

                       <SendTo>~/Default.aspx?ID=$1</SendTo>

                  </RewriterRule>

              </Rules>

         </RewriterConfig>

     

    然后在<system.web></system.web>中加入:

    <httpHandlers>

       <add verb="*" path="*.aspx"

            type="URLRewriter.RewriterFactoryHandler, URLRewriter" />

    </httpHandlers>

     

    最后在地址栏上键入:http://localhost/Test/2004/12/News.aspx

    效果出来了。


    上面的<LookFor>~/(\d{4})/(\d{2})/News\.aspx</LookFor>这句这正则表达式URL,即被重写的URL,而<SendTo>~/Default.aspx?ID=$1</SendTo>这一句为原始URL地址。其中的$1为第一个正则表达式值(上面例子为:2004),以此类推,第二个即为$2

    方法二:Application_BeginRequest()

    在应用程序中新建一个XML文件,文件内容为:文件名ReWriter.config

    <?xml version="1.0" encoding="utf-8" ?>

    <ReWriterUrls>

         <rule>

              <old>(.*)/News/(\d{4})/Default\.aspx</old>

              <new>http://www.cnblogs.com/Default.aspx?id=$2&amp;type=$3</new>

         </rule>

    </ReWriterUrls>

    在Global.asax文件中的Application_BeginRequest(Object sender, EventArgs e)加入代码:

                  try

                  {

                       string path=Server.MapPath("~/ReWriter.config");

                       XPathDocument myXPathDocument = new XPathDocument(path);

                       XPathNavigator myXPathNavigator = myXPathDocument.CreateNavigator();

                       XPathNodeIterator myXPathNodeIterator =  myXPathNavigator.Select ("//rule");

                       System.Text.RegularExpressions.Regex oReg;

                       string ReWriteUrl;

                       while (myXPathNodeIterator.MoveNext())

                       {

                            //oReg=new Regex(oNode.SelectSingleNode("url/text()").Value);

                            XPathNavigator nav2 = myXPathNodeIterator.Current.Clone();

                           string oldString="",newString="";

                            XPathNodeIterator it2 = nav2.Select("old");

                            while(it2.MoveNext())

                           {

                                oldString = it2.Current.Value;

                                break;

                           }

                           it2 = nav2.Select("new");

                            while(it2.MoveNext())

                           {

                                newString = it2.Current.Value;

                                break;

                           }

                            if(oldString != "" &&  newString != "")

                           {

                                oReg = new System.Text.RegularExpressions.Regex(oldString);

                                if(oReg.IsMatch(Request.Url.ToString()))

                                {

                                     ReWriteUrl = oReg.Replace(Request.Url.ToString(),newString);

                                     HttpContext.Current.RewritePath(ReWriteUrl);

                                     break;

                                }

                           }

                       }

                  }

                  catch

                  {

                  }

    最后在地址栏上键入:http://localhost/Test/News/2004/Default.aspx

    效果出来了。

    http://www.cnblogs.com/HD/archive/2005/06/21/178367.html

    http://blog.csdn.net/showmy/archive/2007/11/01/1861400.aspx

    MSDN有详细绍

    http://msdn.microsoft.com/zh-cn/library/ms972974.aspx

  • 相关阅读:
    23种设计模式
    设计模式中类的关系
    简单工厂模式
    SQL正则表达式
    C#中各种计时器
    C# List 排序
    常见名词解释
    PetaPoco入门
    jQuery UI Dialog
    c# winform 获取当前程序运行根目录
  • 原文地址:https://www.cnblogs.com/sainaxingxing/p/1272601.html
Copyright © 2020-2023  润新知