UrlRewritingNet is an Url rewriting tool for ASP .Net and Elmahis 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 { get; set; }

public string DestinationUrl { get; set; }

public string HttpStatusCode { get; set; }

}

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

urlrewritingnet 域名http状态302 问题(转)的更多相关文章

  1. shell+curl监控网站页面(域名访问状态),并利用sedemail发送邮件

    应领导要求,对公司几个主要站点的域名访问情况进行监控.下面分享一个监控脚本,并利用sendemail进行邮件发送. 监控脚本如下:下面是写了一个多线程的网站状态检测脚本,直接从文件中读出站点地址,然后 ...

  2. shell+curl监控网站页面(域名访问状态),并利用sendemail发送邮件

    应领导要求,对公司几个主要站点的域名访问情况进行监控.下面分享一个监控脚本,并利用sendemail进行邮件发送. 监控脚本如下:下面是写了一个多线程的网站状态检测脚本,直接从文件中读出站点地址,然后 ...

  3. Nginx 301重定向域名

    为何要使用301重定向 在网站建设中需要网页重定向的情况很多:如网页目录结构变动,网页重命名.网页的扩展名改变.网站域名改变等.如果不做重定向,用户的收藏和搜索引擎数据库中的旧地址只能让访客得到一个4 ...

  4. 三、nginx301跳转302跳转

    301跳转设置: server { listen 80; server_name downcc.com; rewrite ^/(.*) http://www.downcc.com/$1 permane ...

  5. 什么是HTTP协议?常用的状态码有哪些?

    一.HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的 ...

  6. 未注册wang域名批量查询工具

    一.支持规则查询 可自定义生成域名进行查询,可生成任意位数的字母数字域名,根据[声母].[韵母]生成单拼,双拼,三拼等域名,还可根据字典生成,支持全拼.首拼识别,全国城市区号.城市全拼.城市首拼.热门 ...

  7. 包含为 HTTP 定义的状态代码的值(枚举)

    using System; namespace System.Net { // 摘要: // 包含为 HTTP 定义的状态代码的值. public enum HttpStatusCode { // 摘 ...

  8. php调用whois接口域名查询

    由两部分组成,一个index.php文件,一个whois的接口文件: <html> <head> <title>域名到期查询</title> <s ...

  9. C#HttpWebResponse请求常见的状态码

    成员名称 说明 Continue 等效于 HTTP 状态 100.Continue 指示客户端可能继续其请求. SwitchingProtocols 等效于 HTTP 状态 101.Switching ...

随机推荐

  1. pipe()管道最基本的IPC机制

    <h4>进程间通信 fork pipe pie_t 等用法(管道机制 通信)</h4>每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之 ...

  2. JBPM4之decision节点:2、好学生|坏学生|超级学生

    JBPM入门系列文章: JBPM4入门——1.jbpm简要介绍 JBPM4入门——2.在eclipse中安装绘制jbpm流程图的插件 JBPM4入门——3.JBPM4开发环境的搭建 JBPM4入门—— ...

  3. 嵌入式 hi3518平台多路码流添加osd

    <span style="font-family:Courier New;"> /******************************************* ...

  4. Effective java笔记8--序列化

    对象的序列化(object serialization)API,它提供了一个框架,用来将对象编码成一个字节流,以及从字节流编码中重新构建对象. 一.谨慎地实现Serializable     要想使一 ...

  5. C++重要知识点小结---2

    C++重要知识点小结--1 :http://www.cnblogs.com/heyonggang/p/3246631.html 1.C++允许程序员声明一个不能有实例对象的类,这样的类惟一的用途是被继 ...

  6. Delphi 实现16进制转字符串及字符串(中文)转16进制

    //-----------------------------------------------//16进制字符转整数,16进制字符与字符串转换中间函数//--------------------- ...

  7. 用正则表达式在注册页面(js/aspx.cs)的验证

    1.验证邮箱(用户名) JS页面中: 首先定义变量和正则 var usermail = $("#usermail" ).val(); var username= /^([a-zA- ...

  8. Intellij IDEA开发第一个Android应用

    1.创建一个项目 File——>New Project——>.......——>Finish 2.创建模块 3.MyActivity.java package com.example ...

  9. 华丽的bootstrap3碰到土鳖IE6

    之前由于看好很容易上手的bootstrap,然后用这个框架写了个网站,对于不会美工和细致设计的攻城师来说,bootstrap是个界面设计的瑞士军刀,三下五除二就能搞定个不算太丑的页面. 吭哧吭哧工作了 ...

  10. linux设置主机名

    第一种方式: hostname 在hostname 命名后面直接加想要更改的主机名,修改成功,键入hostname可以查看修改后的主机名,此种方式会立即生效,但是重启后还原.不会永久修改 第二种方式: ...