Перезапись URL в ASP.NET 3.5 и IIS 7 с использованием модуля HTTP - PullRequest
3 голосов
/ 29 октября 2010

Я занимаюсь разработкой приложения в ASP.NET 3.5 и IIS 7. Я написал модуль HTTP для выполнения перезаписи URL, например, я хочу переписать имя пользователя в идентификатор учетной записи "~ / Profiles / profile.aspx?AccountID = "+ account.AccountID.ToString ();

См. Ниже:

using System;using System.Collections.Generic;используя System.Data;используя System.Configuration;используя System.IO;использование System.Linq;использование System.Web;использование System.Web.Security;использование System.Web.UI;использование System.Web.UI.HtmlControls;использование System.Web.UI.WebControls;использование System.Web.UI.WebControls.WebParts;using 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");
                }
            }
        }
    }
}

Я понимаю, что мне нужно сослаться на этот обработчик в web.config, чтобы заставить его работать, но я не знаю, что мне нужно ввести в web.configфайл и где.Может кто-нибудь, пожалуйста, помогите мне здесь.Кроме того, есть ли какая-либо другая конфигурация, необходимая, чтобы заставить это работать?Нужно ли настраивать IIS?

Заранее спасибо.

С уважением

Уолтер

Ответы [ 2 ]

6 голосов
/ 16 декабря 2010

Зависит от того, используете ли вы IIS7 Classic или Integrated Pipeline Mode.Стандартный способ сделать это в режиме Integrated Pipeline заключается в следующем:

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

Но для безопасности вы, вероятно, захотите поддерживать комбинацию IIS7 Classic / Integrated с постепенным ухудшением IIS5 / 6 (в случае, если ваш*) (dev box использует другую ОС), Рик Страхал рекомендует использовать следующий код в веб-конфигурации для поддержки обоих и обхода неприятной ошибки, выдаваемой 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>

Вы также заметите добавление runAllManagedModulesForAllRequest = "true", это актуально, так как в противном случае код в вашем HttpModule будет выполняться только тогда, когда браузер вызывает файлы .aspx, .ashx, .asmx и т. Д., Которыми управляет.NET Framework.

Кроме того, чтобы фактически переписать URL-адрес (вместо перенаправления пользователя), вам нужно будет использовать метод context.RewritePath(string) внутри вашего обработчика событий.

Способэто работает так, что application.Request.Path поставляется с «дружественной» строкой, которая, как мне кажется, выглядит в вашем приложении следующим образом:

http://www.domain.com/robertp

Что переписывается следующим образом:

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

Для этого вместо использования context.Response.Redirect() вам нужно будет использовать context.RewritePath() следующим образом:

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

... TADA !!

Это должно гарантировать, что URL-адрес, передаваемый на сервер, будет с profiles.aspx?AccountID=59, пока пользователь получаетболее дружественный robertp в их браузере.

Что касается параметров конфигурации, то, пока вы придерживаетесь IIS7, у вас все будет в порядке с настройками веб-конфигурации выше.Когда вы пытаетесь протестировать на своем Dev-компьютере под управлением IIS6 или IIS5, у вас может быть проблема, и это обычно связано с тем, что robertp не имеет распознаваемого расширения файла, поэтому ваш код HttpModule не будет выполняться, пока вы не добавитерасширение файла, использующее .NET ISAPI.

Надеюсь, это было полезно.

0 голосов
/ 29 октября 2010

Попробуйте Managed Fusion URL Rewriter, это сэкономит вам Том ручного программирования для переписывания.

http://urlrewriter.codeplex.com

По крайней мере, он показывает, как настроить обработчик в конфигурации.

Приятной особенностью MF является то, что он поддерживает пользовательские модули, которые делают именно то, что вы делаете выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...