• urlrewritingnet 域名http状态302 问题(转)


    UrlRewritingNet is an Url rewriting tool for ASP .Net and Elmah is a module for logging unhandled errors.

     

    UrlRewritingNet can set a default location for “directory” requests via defaultPage property in <urlrewritingnet> section. When a file without extension is requested the defaultPage value is appended to the original URL. 

     

    Elmah provides a handler for getting the errors summary, usually called elmah.axd. This handler also responds to the followings requests: 

     

    /elmah.axd/rss – RSS errors list feed 

    /elmah.axd/digestrss – RSS digest 

    /elmah.axd/download –  comma separated errors list

    /elmah.axd/about – about page 

    /elmah.axd/stylesheet – the stylesheet used

    /elmah.axd/detail?id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX – html single error summary 

    /elmah.axd/xml?id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX – xml single  error summary

    /elmah.axd/json?id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX – json single error summary 

     

    These requests are like a request for a file with no extension. This is why the  UrlRewritingNet adds the defaultPage value which leads to the 404 Http response. First sign of this behavior is when the generated  html does not contain any CSS style applied.

     

    To fix this situation I simply removed the defaultPage attribute from <urlrewritingnet>.

     

    Now if the default page is not set on IIS, then will get an error when the web site is accessed only by the domain name. This situation was handled by  UrlRewritingNet, but in not a proper way, because it returns a 302 Http response(302 Found) with the location set by the defaultPage attribute value, and I think is not the best solution to give the first page when is about SEO. The drawback when the defaultPage attribute is removed is when the directories in the web site are accessed, it will give a 403.14 – Forbidden(IIS 7). But this can be handled by UrlRewritingNet using a custom UrlRewritingProvider.

     

    During developing this custom provider I noticed it would be better to set and the HttpStatus when the url's are rewriten. So I added a new attribute to the <add/> node called httpStatusCode.

     

    Creating a new UrlRewriterNet is very simple:

     

    public class RootProvider : UrlRewritingProvider

    {

        public override RewriteRule CreateRewriteRule()

        {

            return new RootRule();

        }

        }

    The class RootRule does all the logic:

     

     public class RootRule : RewriteRule

        {

        public override void Initialize(UrlRewritingNet.Configuration.RewriteSettings rewriteSettings)

        {

            base.Initialize(rewriteSettings);

            VirtualUrl = rewriteSettings.GetAttribute("virtualUrl""");

            DestinationUrl = rewriteSettings.GetAttribute("destinationUrl""");

            HttpStatusCode = rewriteSettings.GetAttribute("httpStatusCode""");

     

        }

        public override bool IsRewrite(string requestUrl)

        {      

            return requestUrl == VirtualUrl;

        }

        public override string RewriteUrl(string url)        

        {

            if (!String.IsNullOrEmpty(HttpStatusCode))

            {

            HttpStatusCodeHandler handler = null;

            switch (HttpStatusCode)

            {

                case "404" :

                handler = new _404Handler(DestinationUrl);

                break;

                case "301":

                handler = new _301Handler(DestinationUrl);

                break;

                case "302":

                handler = new _302Handler(DestinationUrl);

                break;

                default:

                handler = new NotImplementedHandler(DestinationUrl);

                break;

            }

            handler.Execute();

            return null;

            }

           

            return DestinationUrl;

        }

        public string VirtualUrl { getset; }

        public string DestinationUrl { getset; }

        public string HttpStatusCode { getset; }

        }

     

    The  RootRule class instantiates a specific handler, depending by the http status code.

     

    I created a base class to define the model of how a status code could be handled.

     

    public class HttpStatusCodeHandler {

        protected string destinationUrl;

        protected HttpStatusCodeHandler() { }

        public HttpStatusCodeHandler(string DestinationUrl) {

            destinationUrl = DestinationUrl;

        }        

        public virtual void Execute() {

            throw new NotImplementedHttpStatusException();

        }

        }

     

    For sample when a directory is accessed it can be used a 404 response. 

     

        public sealed class _404Handler : HttpStatusCodeHandler

        {

        private _404Handler() { }

        public _404Handler(string DestinationUrl) : base(DestinationUrl) { }

        public override void Execute()

        {

            HttpContext.Current.Response.Clear();

            HttpContext.Current.Response.Status = "404 Not Found";

            HttpContext.Current.Response.StatusDescription = "Not Found";

            HttpContext.Current.Response.Write(File.ReadAllText(HttpContext.Current.Server.MapPath(destinationUrl)));

            HttpContext.Current.Response.End();

        }

        }

     

    The 302 and 301 reponses needs to add the Location in the header response. The location contains the new URL where the old resource exists now. 

     

        public sealed class _302Handler : HttpStatusCodeHandler

        {

        private _302Handler() { }

        public _302Handler(string DestinationUrl) : base(DestinationUrl) { }

        public override void Execute()

        {

            HttpContext.Current.Response.Clear();

            HttpContext.Current.Response.Status = "302 Found";

            HttpContext.Current.Response.StatusDescription = "Found";

            HttpContext.Current.Response.AddHeader("Location", destinationUrl);

            HttpContext.Current.Response.End();

        }

        }

        public sealed class _301Handler : HttpStatusCodeHandler

        {

        private _301Handler() { }

        public _301Handler(string DestinationUrl) : base(DestinationUrl) { }

        public override void Execute()

        {

            HttpContext.Current.Response.Clear();

            HttpContext.Current.Response.Status = "301 Moved Permanently";

            HttpContext.Current.Response.StatusDescription = "Moved Permanently";

            HttpContext.Current.Response.AddHeader("Location", destinationUrl);

            HttpContext.Current.Response.End();

        }

        }

        public sealed class NotImplementedHandler : HttpStatusCodeHandler

        {

        private NotImplementedHandler() { }

        public NotImplementedHandler(string DestinationUrl) : base(DestinationUrl) { }

        public override void Execute()

        {

            throw new NotImplementedHttpStatusException();

        }

        }

        public class NotImplementedHttpStatusException : Exception

        {

        public override string Message

        {

            get

            {

            return "NotIplementedHttpStatusException";

            }

        }

        }

     

    Now in the RewriteRule section I define some rules:

     

    to define a default page when the folder “products” is accessed

     

    <add name="products" virtualUrl="/products/" destinationUrl="/products/latest_products.asp" httpStatusCode="302"rewriteUrlParameter="ExcludeFromClientQueryString" ignoreCase="true" provider="RootProvider"/>    

     

    to say that a page is permanently moved and the new location is other page

     

    <add name="about" virtualUrl="/pages.asp?func=get_content&amp;page_id=1" destinationUrl="/about.asp" httpStatusCode="301"rewriteUrlParameter="IncludeQueryStringForRewrite" ignoreCase="true" provider="RootProvider"/>

     

    These redirects are very helpful when you want to keep the search engines rankings. 

    原文链接:http://csharpin.blogspot.com/2009/03/using-urlrewritingnet-and-elmah.html

  • 相关阅读:
    long类型的数据转化为时间
    取到数组中对应位置的文字,并且转成大写
    无key值的json数组解析
    mongo-2ds索引对超过半球范围的适用性测试
    mongoDB-Cannot change the size of a document in a capped collection:
    springboot
    左中右布局的五种实现方式
    spring boot 常见的配置问题
    移动端H5拍照代码实现及外网部署
    JAVA数据库操作回滚小结
  • 原文地址:https://www.cnblogs.com/thinkingthigh/p/4225509.html
Copyright © 2020-2023  润新知