大家在进行Web程序支付时,为了拓展搜寻引擎优化(SEO),往往要求对web的拜会地址进行优化,如将http://localhost/Default.aspx?tab=performance修改为http://localhost/Default_performance.aspx,后2个地点可以越来越好地被搜索引擎搜索到,从而完成了搜索引擎优化的指标。微软有三个开源类库URLRewriter能够分外便宜地完毕url改写,通过配备在web.config文件中的映射表将用户的呼吁重定向到具体的页面中,笔者在“运用ULX570LRewriter举办ULANDL重写失效”一文中详尽介绍了什么样运用这几个类库,该类库是透过asp.net的httpmodules或httphandles来施行的,但只要网站的宿主服务器不协助asp.net
httpmodules和httphandles,则该成效便失效了,那时我们得以经过global中的application_beginrequest事件来拓展url重定向。本文在U昂科雷LRewriter类库的根基上进行了创新,并提交了三个相持完好的消除方案。

  大家的精雕细刻是两手空空在UOdysseyLRewriter的底蕴之上的,所以U宝马X3LRewriter原有的事物即便能用,大家都得以一贯拿过来,当然,倒霉的东西要废弃!

  URubiconLRewriter的映射表是直接写在web.config文件中的,要让web.config能识别映射表,必须在configSections节中添加section,告诉程序如何正确分析web.config中未被辨认的剧情,如原URubiconLRewriter就供给在web.config中添加<section name=”RewriterConfig”
type=”UENCORELRewriter.Config.RewriterConfigSerializerSectionHandler,
UPRADOLRewriter”/>。小编觉着那么些方式并糟糕,首先你必要独自去编写三个类库来解析xml,并在web.config中展开布置,我们壹齐能够省去这一步。url的映射表能够独自写到3个xml文件中,当程序运营时将xml加载到应用程序缓存中,并安装1个缓存文件注重项,那样每当管理员修改完映射表后就足以马上见效。

  别的小编期待扶助url的双向改写,即下边提到的多少个url,当用户输入第三个url时程序会将呼吁发送到第一个url,但浏览器中呈现的url不变;当用户输入第二个url时,自动跳转到第三个url,此时浏览器中体现的是第贰个url,不过请求仍旧是首先个url。听起来是否有点绕啊?不妨,其实也很简短,基本的须要就是客户原本网址中的很多页面在走访时都带了数不胜数参数,做url改写时都换来新的url了,那时旧的url还是可以用,客户想的正是当输入原来旧的url时能半自动跳转到新的url。那个就是url的双向改写!那二种艺术能够独家通过Context.RewritePath()和Context.Response.Redirect()方法来落到实处,上面我们来看现实的完结。

  首先是映射表的贯彻。我在UEvoqueLRewriter原有映射表的底蕴上做了一点改观,正是给ReWriterRule添加了三个IsDirect属性,该属性可选,私下认可值为False,当班值日为真时假诺用户请求的url相配则会进展跳转,不然只是实行呼吁映射。 

<?xml version=”1.0″?>
<ReWriterConfig xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema"&gt;
  <Rules>
    <ReWriterRule>
      <LookFor>~/Default_(\w+)\.aspx</LookFor>
      <SendTo>~/Default.aspx?tab=$1</SendTo>
    </ReWriterRule>
    <ReWriterRule IsDirect=”true”>
      <LookFor>~/Default\.aspx\?tab=(\w+)</LookFor>
      <SendTo>~/Default_$1.aspx</SendTo>
    </ReWriterRule>
  </Rules>
</ReWriterConfig>

  该映射表帮助正则表明式,下边是应和的实体类,用来展开反种类化。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace URLRewriterTest
{
    [Serializable]
    public class ReWriterConfig
    {
        public ReWriterRule[] Rules;
    }

    [Serializable]
    public class ReWriterRule
    {
        private bool _isRedirect = false;

        [System.Xml.Serialization.XmlAttribute(“IsDirect”)]
        public bool IsRedirect
        {
            get { return _isRedirect; }
            set { this._isRedirect = value; }
        }
        public string LookFor { get; set; }
        public string SendTo { get; set; }
    }
}

  上面那个类用来得到映射表,当程序第三次运维时会将映射表反连串化的结果放到大局应用程序缓存中。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Serialization;
using System.IO;
using System.Web.Caching;

namespace URLRewriterTest
{
    public class ReWriterConfiguration
    {
        public static ReWriterConfig GetConfig(string filename)
        {
            if (HttpContext.Current.Cache[“RewriterConfig”] == null)
            {
                ReWriterConfig config = null;
                // Create an instance of the XmlSerializer specifying type and namespace.   
                XmlSerializer serializer = new XmlSerializer(typeof(ReWriterConfig));

                // A FileStream is needed to read the XML document.   
                using (Stream reader = new FileStream(filename, FileMode.Open))
                {
                    // Declare an object variable of the type to be deserialized.   
                    config = (ReWriterConfig)serializer.Deserialize(reader);
                }
                HttpContext.Current.Cache.Insert(“RewriterConfig”, config, new CacheDependency(filename));
            }
            return (ReWriterConfig)HttpContext.Current.Cache[“RewriterConfig”];     
        }
    }
}

  大家照样须要原U大切诺基LRewriter类库中的ReWriterUtils类中的方法,可是对在那之中RewriteUrl方法进行了一点小的变更,扩展了3个isRedirect参数,用来控制是履行Context.RewritePath()方法恐怕Context.Response.Redirect()方法,上面是源代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace URLRewriterTest
{
    public class ReWriterUtils
    {
        /// <summary>
        /// Rewrite’s a URL using <b>HttpContext.RewriteUrl()</b>.
        /// </summary>
        /// <param name=”context”>The HttpContext object to rewrite the URL to.</param>
        /// <param name=”isRedirect”>Redirect or rewrite path.</param>
        /// <param name=”sendToUrl”>The URL to rewrite to.</param>
        public static void RewriteUrl(HttpContext context, string sendToUrl, bool isRedirect)
        {
            string x, y;
            RewriteUrl(context, sendToUrl, isRedirect, out x, out y);
        }

        /// <summary>
        /// Rewrite’s a URL using <b>HttpContext.RewriteUrl()</b>.
        /// </summary>
        /// <param name=”context”>The HttpContext object to rewrite the URL to.</param>
        /// <param name=”sendToUrl”>The URL to rewrite to.</param>
        /// <param name=”isRedirect”>Redirect or rewrite path.</param>
        /// <param name=”sendToUrlLessQString”>Returns the value of sendToUrl stripped of the querystring.</param>
        /// <param name=”filePath”>Returns the physical file path to the requested page.</param>
        public static void RewriteUrl(HttpContext context, string sendToUrl, bool isRedirect, out string sendToUrlLessQString, out string filePath)
        {
            // see if we need to add any extra querystring information
            if (context.Request.QueryString.Count > 0)
            {
                if (sendToUrl.IndexOf(‘?’) != -1)
                    sendToUrl += “&” + context.Request.QueryString.ToString();
                else
                    sendToUrl += “?” + context.Request.QueryString.ToString();
            }

            // first strip the querystring, if any
            string queryString = String.Empty;
            sendToUrlLessQString = sendToUrl;
            if (sendToUrl.IndexOf(‘?’) > 0)
            {
                sendToUrlLessQString = sendToUrl.Substring(0, sendToUrl.IndexOf(‘?’));
                queryString = sendToUrl.Substring(sendToUrl.IndexOf(‘?’) + 1);
            }

            // grab the file’s physical path
            filePath = string.Empty;
            filePath = context.Server.MapPath(sendToUrlLessQString);

            if (isRedirect)
            {
                // redirect the pathXML 1
                context.Response.Redirect(“~/” + sendToUrlLessQString);
            }
            else
            {
                // rewrite the pathXML 2
                context.RewritePath(“~/” + sendToUrlLessQString, String.Empty, queryString);
            }

            // NOTE!  The above RewritePath() overload is only supported in the .NET Framework 1.1
            // If you are using .NET Framework 1.0, use the below form instead:
            // context.RewritePath(sendToUrl);
        }

        /// <summary>
        /// Converts a URL into one that is usable on the requesting client.
        /// </summary>
        /// <remarks>Converts ~ to the requesting application path.  Mimics the behavior of the 
        /// <b>Control.ResolveUrl()</b> method, which is often used by control developers.</remarks>
        /// <param name=”appPath”>The application path.</param>
        /// <param name=”url”>The URL, which might contain ~.</param>
        /// <returns>A resolved URL.  If the input parameter <b>url</b> contains ~, it is replaced with the
        /// value of the <b>appPath</b> parameter.</returns>
        public static string ResolveUrl(string appPath, string url)
        {
            if (url.Length == 0 || url[0] != ‘~’)
                return url;        // there is no ~ in the first character position, just return the url
            else
            {
                if (url.Length == 1)
                    return appPath;  // there is just the ~ in the URL, return the appPath
                if (url[1] == ‘/’ || url[1] == ‘\\’)
                {
                    // url looks like ~/ or ~\
                    if (appPath.Length > 1)
                        return appPath + “/” + url.Substring(2);
                    else
                        return “/” + url.Substring(2);
                }
                else
                {
                    // url looks like ~something
                    if (appPath.Length > 1)
                        return appPath + “/” + url.Substring(1);
                    else
                        return appPath + url.Substring(1);
                }
            }
        }
    }
}

  最后就是编辑Global中的Application_BeginRequest事件了,在原本URubiconLRewriter的底子上稍作修改。

protected void Application_BeginRequest(object sender, EventArgs e)
{
    string requestedPath = Request.RawUrl.ToString();

    // get the configuration rules
    string filename = Context.Server.MapPath(“.”) + “//ReWriterRules.xml”;
    ReWriterConfig rules = ReWriterConfiguration.GetConfig(filename);

    // iterate through each ruleXML 3
    for (int i = 0; i < rules.Rules.Length; i++)
    {
        // get the pattern to look for, and Resolve the Url (convert ~ into the appropriate directory)
        string lookFor = “^” + ReWriterUtils.ResolveUrl(Context.Request.ApplicationPath, rules.Rules[i].LookFor) + “$”;

        // Create a regex (note that IgnoreCase is setXML 4)
        Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);

        // See if a match is found
        if (re.IsMatch(requestedPath))
        {
            // match found – do any replacement needed
            string sendToUrl = ReWriterUtils.ResolveUrl(Context.Request.ApplicationPath, re.Replace(requestedPath, rules.Rules[i].SendTo));

            // Rewrite or redirect the URL
            ReWriterUtils.RewriteUrl(Context, sendToUrl, rules.Rules[i].IsRedirect);
            break;        // exit the for loop
        }
    }
}

  好了,马到成功!使用方面包车型客车映射表,当你输入http://localhost/Default_performance.aspx时访问通常,事实上Default_背后能够添加任何字符,那么些字符都将作为Default.aspx页面tab参数的值。同时,当您输入http://localhost/Default.aspx?tab=performance时页面会自动跳转到前面二个url,tab参数的值将被用作url的一有个别。

URLRewriterTest.rar下载

相关文章

网站地图xml地图