简体   繁体   English

使用HTTP模块在ASP.NET 3.5和IIS 7中重写URL

[英]URL Rewrite in ASP.NET 3.5 and IIS 7 using HTTP Module

I am developing an application in ASP.NET 3.5 and IIS 7. I have written an HTTP Module to perform URL Rewrite, for instance, I want to rewrite a username to an Account ID "~/Profiles/profile.aspx?AccountID=" + account.AccountID.ToString(); 我正在ASP.NET 3.5和IIS 7中开发一个应用程序。我编写了一个HTTP模块来执行URL重写,例如,我想将用户名重写为帐户ID“〜/ Profiles / profile.aspx?AccountID =” + account.AccountID.ToString();

See below: 见下文:

using System; 使用系统; using System.Collections.Generic; 使用System.Collections.Generic; using System.Data; 使用System.Data; using System.Configuration; 使用System.Configuration; using System.IO; 使用System.IO; using System.Linq; 使用System.Linq; using System.Web; 使用System.Web; using System.Web.Security; 使用System.Web.Security; using System.Web.UI; 使用System.Web.UI; using System.Web.UI.HtmlControls; 使用System.Web.UI.HtmlControls; using System.Web.UI.WebControls; 使用System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; 使用System.Web.UI.WebControls.WebParts; using System.Xml.Linq; 使用System.Xml.Linq;

public class UrlRewrite : IHttpModule
{
    private AccountRepository _accountRepository;
    private WebContext _webContext;

    public UrlRewrite()
    {
        _accountRepository = new AccountRepository();
        _webContext = new WebContext();
    }

    public void Init(HttpApplication application)
    {
        // Register event handler.
        application.PostResolveRequestCache +=
            (new EventHandler(this.Application_OnAfterProcess));
    }

    public void Dispose()
    {
    }

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

        string[] extensionsToExclude = { ".axd", ".jpg", ".gif", ".png", ".xml", ".config", ".css", ".js", ".htm", ".html" };
        foreach (string s in extensionsToExclude)
        {
            if (application.Request.PhysicalPath.ToLower().Contains(s))
                return;
        }

        if (!System.IO.File.Exists(application.Request.PhysicalPath))
        {
            if (application.Request.PhysicalPath.ToLower().Contains("blogs"))
            {

            }
            else if (application.Request.PhysicalPath.ToLower().Contains("forums"))
            {

            }
            else
            {

                string username = application.Request.Path.Replace("/", "");

                Account account = _accountRepository.GetAccountByUsername(username);

                if (account != null)
                {
                    string UserURL = "~/Profiles/profile.aspx?AccountID=" + account.AccountID.ToString();
                    context.Response.Redirect(UserURL);
                }
                else
                {
                    context.Response.Redirect("~/PageNotFound.aspx");
                }
            }
        }
    }
}

I understand that I need to reference this Handler in web.config to get it to work but I don't know what I need to enter in the web.config file and where. 我知道我需要在web.config中引用这个Handler来使它工作,但我不知道我需要在web.config文件中输入什么以及在哪里。 Can some please help me here. 有人可以帮帮我吗。 Also, is there any other configuration needed to get this to work? 此外,是否需要任何其他配置才能使其工作? Do I need to configure IIS? 我需要配置IIS吗?

Thanks in advance. 提前致谢。

Regards 问候

Walter 沃尔特

Depends on whether you are using IIS7 Classic or Integrated Pipeline Mode. 取决于您使用的是IIS7 Classic还是集成管道模式。 The standard way to do this with Integrated Pipeline mode is as follows: 使用Integrated Pipeline模式执行此操作的标准方法如下:

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <add name="UrlRewrite" type="MyLibrary.UrlRewrite" />
  </modules>
</system.webServer>

But to be safe you probably want to support a combination of IIS7 Classic/Integrated with graceful degradation on IIS5/6 (in case your dev box uses a different OS), Rick Strahal recommends using the following code on the web config to support both and bypass the nasty error thrown by IIS if you make it backwards-compatible: 但为了安全起见,您可能希望在IIS5 / 6上支持IIS7 Classic / Integrated和优雅降级的组合(如果您的开发盒使用不同的操作系统), Rick Strahal建议在Web配置上使用以下代码来支持和绕过IIS引发的令人讨厌的错误,如果你使它向后兼容:

<system.web>
  <httpModules>
    <add name="UrlRewrite" type="MyLibrary.UrlRewrite" />
  </httpModules>
</system.web>
<system.webServer>
  <validation validateIntegratedModeConfiguration="false"/>
  <modules runAllManagedModulesForAllRequests="true">
    <add name="UrlRewrite" type="MyLibrary.UrlRewrite" />
  </modules>
</system.webServer>

You will also notice an addition of runAllManagedModulesForAllRequest="true", this is relevant since otherwise the code in your HttpModule will only be executed when the browser calls for .aspx, .ashx, .asmx, etc files that are managed by the .NET framework. 您还会注意到runAllManagedModulesForAllRequest =“true”的添加,这是相关的,否则您的HttpModule中的代码只会在浏览器调用由.NET管理的.aspx,.ashx,.asmx等文件时执行。框架。

Also, in order to actually rewrite the url (instead of redirect the user) you will need to use the context.RewritePath(string) method inside your event handler. 此外,为了实际重写url(而不是重定向用户),您需要在事件处理程序中使用context.RewritePath(string)方法。

The way this works is that the application.Request.Path comes in with a 'friendly' string, which I imagine looks like this in your application: 这种方式的工作方式是application.Request.Path带有一个'友好'字符串,我想你在你的应用程序中看起来像这样:

http://www.domain.com/robertp http://www.domain.com/robertp

Which gets rewritten as follows: 哪个被重写如下:

http://www.domain.com/Profiles/profile.aspx?AccountID=59 http://www.domain.com/Profiles/profile.aspx?AccountID=59

To do this instead of using context.Response.Redirect() you will need to use context.RewritePath() as follows: 要执行此操作而不是使用context.Response.Redirect()您将需要使用context.RewritePath() ,如下所示:

string UserURL = "~/Profiles/profile.aspx?AccountID=" + account.AccountID.ToString();
context.RewritePath(UserURL);

... TADA!! ... TADA !!

This should ensure that the url being passed through to the server is the one with profiles.aspx?AccountID=59 while the user gets a more friendly robertp on their browser. 这应确保传递到服务器的URL是具有profiles.aspx?AccountID=59的URL,而用户在其浏览器上获得更友好的robertp

As for configuration options, so long as you stick to IIS7 you should be fine with the web config settings above. 至于配置选项,只要你坚持使用IIS7就可以使用上面的web配置设置了。 Its when you try testing on your Dev PC running IIS6 or IIS5 that you might have a problem and this will generally revolve around the fact that robertp does not have a recognizable file extension so your HttpModule code will not be executed unless you add a file extension that uses the .NET ISAPI. 当您尝试在运行IIS6或IIS5的Dev PC上进行测试时,您可能会遇到问题,这通常会围绕robertp没有可识别的文件扩展名这一事实,因此除非您添加文件扩展名,否则您的HttpModule代码将不会被执行使用.NET ISAPI。

Hope that was useful. 希望这很有用。

Try the Managed Fusion URL Rewriter, it will save you a Tom of manual programming for rewrites. 尝试使用托管融合URL重写器,它将为您节省手动编程的Tom以进行重写。

http://urlrewriter.codeplex.com http://urlrewriter.codeplex.com

At the very least it shows you how to setup a handler in the config. 它至少会告诉你如何在配置中设置一个处理程序。

Nice thing about MF is that it supports custom modules got doing exactly what you are doing above. 关于MF的好处是它支持自定义模块完全按照上面的方式执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM