1

我在 Visual Studio 2012 内的 Cassini 开发人员服务器中运行,我需要将客户端从旧.asp页面重定向到.aspx页面。

注意:理想情况下,我会将客户端重定向.asp到友好的 url,然后在内部进行重写.aspx

POST /ResetClock.asp

HTTP/1.1 307 Temporary Redirect
Location: //stackoverflow.us/ResetClock

然后在内部:

POST /ResetClock

重写为/ResetClock.ashx(是的,我将其更改为.ashx;这是 url 重写的优点)。

就像汉塞尔曼所做的那样

这很像Scott Hanselman 所做的:

  • 要求/foo.html
  • 给客户一个重定向到/foo
  • 客户要求/foo
  • 被改写成/foo.html

尝试的黑客攻击

我尝试了黑客解决方案;更改.asp页面以强制重定向到.ashx(并在另一天与 url 重写语法作斗争):

重置时钟.asp

<% 
   Response.Redirect("ResetClock.aspx")
   Response.End 
%>

除了 Cassini 根本不提供.asp页面:

不提供此类页面。

说明:您请求的页面类型未提供服务,因为它已被明确禁止。扩展名“.asp”可能不正确。请查看下面的 URL 并确保其拼写正确。

请求的 URL: /WebSite/FetchTimes.asp

这指出了一个相关的问题。我最终使用的解决方案不需要 IIS7.5 上尚不可用的任何东西。它不需要任何需要访问 IIS 管理工具的东西;并且必须完全存在于网站中(例如web.config)。

问题

我如何重新写入.asp更 ASP.net 的东西?

编辑:更改GET为 aPOST以阻止那些想知道为什么307 Temporary Redirect而不是302 Foundor的挑剔者303 See Other

4

1 回答 1

2

解决方案是创建一个IHttpModule. HttpModules 让您拦截每个请求,并根据需要做出反应。

第一步是创建管道IHttpModule

class UrlRewriting : IHttpModule
{
    public void Init(HttpApplication application)
    {
        application.BeginRequest += new EventHandler(this.Application_BeginRequest);
        application.EndRequest += new EventHandler(this.Application_EndRequest);
    }

    public void Dispose()
    {
        //Nothing to do here
    }

    private void Application_BeginRequest(object sender, EventArgs e)
    {
        HttpApplication application = (HttpApplication)sender;
        HttpContext context = application.Context;
    }

    private void Application_EndRequest(object sender, EventArgs e)
    {
    }
}

然后在文件中注册我们的HttpHandlerweb.config

网络配置

<configuration>
   <system.web>
      <httpModules>
         <add name="UrlRewriting" type="UrlRewriting"/>
      </httpModules>
   </system.web>
</configuration>

现在我们有一个方法 ( Application_BeginRequest) 将在每次发出请求时运行。

如果他们要求 ASP 页面,则发出客户端重定向

首要任务是将客户端重定向到“干净”的表单。例如,请求/File.asp被重定向到/File

private void Application_BeginRequest(object sender, EventArgs e)
{
   HttpApplication application = (HttpApplication)sender;
   HttpContext context = application.Context;

   //Redirct any requests to /File.asp into a /File
   if (context.Request.Url.LocalPath == VirtualPathUtility.ToAbsolute("~/File.asp"))
   {
      //Be sure to issue a 307 Temporary Redirect in case the client issued a POST (i.e. a non-GET)
      //If we issued 302 Found, a buggy client (e.g. Chrome, IE, Firefox) might convert the POST to a GET.
      //If we issued 303 See Other, the client is required to convert a POST to a GET.
      //If we issued 307 Temporary Redirect, the client is required to keep the POST method
      context.Response.StatusCode = (int)HttpStatusCode.TemporaryRedirect;
      context.Response.RedirectLocation = VirtualPathUtility.ToAbsolute("~/File");
      context.Response.End();
   }
}

然后内部重写

现在客户将要求/File我们必须在内部将其重新写入一个.aspx,或者在我的情况下,一个.ashx文件:

private void Application_BeginRequest(object sender, EventArgs e)
{
   HttpApplication application = (HttpApplication)sender;
   HttpContext context = application.Context;

   //Redirct any requests to /ResetClock.asp into a /File
   if (context.Request.Url.LocalPath == VirtualPathUtility.ToAbsolute("~/ResetClock.asp"))
   {
      //Be sure to issue a 307 Temporary Redirect in case the client issued a POST (i.e. a non-GET)
      //If we issued 302 Found, the buggy client might convert the POST to a GET.
      //If we issued 303 See Other, the client is required to convert a POST to a GET.
      //If we issued 307 Temporary Redirect, the client is required to keep the POST method
      context.Response.StatusCode = (int)HttpStatusCode.TemporaryRedirect;
      context.Response.RedirectLocation = VirtualPathUtility.ToAbsolute("~/ResetClock");
      context.Response.End();
   }

   //Rewrite clean url into actual handler
   if (context.Request.Url.LocalPath == VirtualPathUtility.ToAbsolute("~/ResetClock"))
   {
      String path = "~/ResetClock.ashx"; //no need to map the path
      context.Server.Execute(path, true);

      //The other page has been executed
      //Do not continue or we will hit the 404 of /ResetClock not being found
      context.Response.End();
   }
}

IIS 包含一些基本的 url 重定向

从一些未知版本的 IIS 开始,他们添加了一种(现在模拟的)URL 重写形式。它不会发出客户端重定向,只会进行内部重写。但至少它可以用来解决我的问题(响应带有 ASP.net 内容的 ASP 页面):

网络配置

<configuration>
   <system.web>
      <urlMappings>
         <add url="~/ResetClock.asp" mappedUrl="~/ResetClock.ashx"/>
      </urlMappings>
   </system.web>
</configuration>

客户端似乎仍会在 处找到资源/ResetClock.asp,但响应的内容将来自/ResetClock.ashx.

注意:任何代码都会发布到公共领域。无需归属。

于 2013-10-01T14:16:20.137 回答