Может ли .NET перехватывать и изменять css файлы? - PullRequest
13 голосов
/ 01 июня 2011

ОБНОВЛЕНИЕ 1:

Теперь я настроил IIS6, чтобы .NET мог обрабатывать вызовы файлов .css.Что мне теперь нужно сделать, чтобы заставить его изменять CSS-файлы на основе реферального URL?Поэтому, если реферальный URL равен http://intranet/,, он должен продолжать вызывать старые таблицы стилей.Если реферальный URL равен http://intranetv2/,, он должен вызывать новую таблицу стилей.


ОРИГИНАЛЬНЫЙ ВОПРОС:

Фон:

У меня есть 2 поисковых системы.1 старый, а другой новый (этап разработки).Поисковая система 1 находится на domain1.com, а поисковая система 2 - на domain2.com.Оба домена находятся на одном сервере.Оба выполняют поиск веб-страниц на domain1.com в зависимости от того, что пользователь вводит в поисковые системы.Разница между двумя поисковыми системами заключается в том, что новая работает быстрее, дает более точные результаты и имеет значительно улучшенный пользовательский интерфейс.Обе поисковые системы останутся живыми, так что пользователи могут привыкнуть к новой в свое время, вместо того, чтобы просто бросить их в глубокий конец и полностью удалить старую поисковую систему.

В любом случае, достаточнофон, в основном, поскольку доступные для поиска страницы находятся на старом доменном имени со старой поисковой системой, тогда как новая поисковая система находится на новом доменном имени, ...

Вопрос:

... могу ли я использовать HttpModule, или другую часть .NET, или что-то из IIS6 даже для захвата ссылок на страницы, сгенерированных новой поисковой системой, и динамического изменения файла css, прикрепленного к старым страницам с возможностью поискана старом домене?

Причина:

По сути, это выглядит как совершенно новый сайт, где поисковая система на старом домене используется длядля доступа к страницам в старом домене используется старая таблица стилей, но если для поиска файлов в старом домене используется поисковая система в новом доменеname, новая таблица стилей должна использоваться, чтобы старые страницы выглядели новыми.Так как существует множество доступных для поиска страниц, в районе 10000, редактирование каждой страницы для добавления оператора if для проверки имени домена реферала перед добавлением таблицы стилей на страницы нереально.

Среда:

Старая поисковая система вместе с поисковыми страницами на старом домене использует .net 1.something, но новая поисковая система на новом доменном имени использует .net3.5, и я использую vb.net для страниц asp.net.Сервер является сервером IIS6.

Ответы [ 7 ]

2 голосов
/ 28 июля 2011
  1. В IIS настройте HttpHandler для получения всех типов файлов, которые вы хотите (говорит, что вы это сделали)
  2. user Server.MapPath() на HttpRequest.Url.AbsolutePath для получения физического пути
  3. Изменить путь в соответствии с доменом
  4. Записать файл в поток ответов.

Вот обработчик (упрощенный), который я обычно использую для сервера альтернативных файлов для разных доменов:

using System;
using System.IO;
using System.Web;
public class MultiDomainFileHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        string filePath = GetDomainSpecificFilePath(context.Request.Url.Host,
            context.Server.MapPath(context.Request.Url.AbsolutePath));

        if (File.Exists(filePath))
        {
            switch (Path.GetExtension(filePath).ToLower())
            {
                case ".css": context.Response.ContentType = "text/css"; break;
                case ".jpg":
                case ".jpeg": context.Response.ContentType = "image/jpeg"; break;
                //other types you want to handle
                default: context.Request.ContentType = "application/octet-stream"; break;
            }
            context.Response.WriteFile(filePath); //Write the file to response
        }
        else context.Response.StatusCode = 404;
    }

    private string GetDomainSpecificFilePath(string domain, string originalPath)
    {
        string prefix = "";
        switch (domain.ToLower())
        {
            case "intranetv2": prefix = FILE_PREFIX_INTRANETV2; break;
            case "www.example.com": prefix = FILE_PREFIX_EXAMPLE_DOT_COM; break;
            //other domains you want to handle
        }
        string dir = Path.GetDirectoryName(originalPath);
        string fileName = prefix + Path.GetFileName(originalPath);
        return Path.Combine(dir, fileName);
    }

    const string FILE_PREFIX_INTRANETV2 = "v2.", FILE_PREFIX_EXAMPLE_DOT_COM = "ex.com.";
    public bool IsReusable { get { return false; } }
}

Теперь вам просто нужно иметь альтернативные файлы в одних и тех же каталогах.Например:

/ Images / logo.jpg

/ Images / v2.logo.jpg

/ Styles / mystyle.css

/ Styles / v2.mystyle.css

Надеюсь, это поможет:)

1 голос
/ 21 июля 2011

Я бы не рекомендовал использовать httpModule, так как он будет вызываться для каждого запроса, который может ухудшить производительность.Принимая во внимание, что вы можете использовать httpHandlers для обработки только определенных путей.Поэтому, мой голос должен был бы использовать httpHandlers.

Но есть сбой.По умолчанию IIS 6 не передает запросы на расширение ASP.Net (кроме расширений .aspx, .ashx, .axd и т. Д.) В ASP.Net по умолчанию.

Поэтому вам необходимо добавить модуль ISAPI для расширения CSS, чтобы передать запрос aspnet_isapi.dll (полный путь можно найти в обработчике расширения .aspx).

Эта ссылка может помочь в настройке модуля ISAPI.

Как только ASP.Net начнет обрабатывать расширение .CSS, напишите httpHandler с вашей логикой и добавьте следующую строку в раздел httphandlers в web.config file

Скажите, что ваш httpHandler CSSHttpHandler, тогда код будет примерно таким:

<add verb="HEAD,GET" path="*.css" type="CSSHttpHandler">

Надеюсь, это поможет.

1 голос
/ 08 июня 2011

На основе доменного имени вы можете динамически управлять частью страницы из кода (файлы .vb или .cs или даже класс). Это даст вам возможность заменить файл CSS на основе имени домена. Захватите доменное имя в коде и затем замените файл / ссылку на css, затронув всю часть кода. Вы можете сделать это в C # или в VB.

1 голос
/ 01 июня 2011

Я делаю что-то похожее для файлов, обслуживаемых нашей системой управления контентом. Если обработчик http включен, он проверяет имя файла и путь, чтобы определить, есть ли у пользователя доступ к ресурсу. Если пользователь это делает, он передает файл в потоковом режиме, в противном случае он возвращает 401 не авторизованного.

Я не понимаю, почему вы не можете использовать обработчик для перехода в конвейер для файла css, проверки имени хоста и потоковой передачи другого файла css (если применимо). Это просто в IIS7 со встроенным конвейером (вы не указали), но также возможно в IIS6, если вы разрешите расширение css обрабатывать .net.

Дайте мне знать, если вы заинтересованы в таком подходе, и я отследю некоторый код.

Редактировать - вот код

Это не совсем то, что вы ищете, но вы можете получить некоторые идеи.

ПРИМЕЧАНИЕ. Это в IIS7 со встроенным конвейером, поэтому в IIS6 вам придется внести изменения, чтобы файлы .css обрабатывались процессом .net.

Public Class FileManagerFileAuthorization
    Implements IHttpHandler

    Public ReadOnly Property IsReusable As Boolean Implements System.Web.IHttpHandler.IsReusable
        Get
            Return True
        End Get
    End Property

    Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest

        Dim req As HttpRequest = context.Request
        Dim absolutePath As String = req.Path
        Dim fileName As String = Path.GetFileName(absolutePath)
        Dim physicalPathAndFileName As String = HttpContext.Current.Server.MapPath(absolutePath)

        If File.Exists(physicalPathAndFileName) Then

            ' roles that the user is part of. If the user is not authenticated they are part of the public role only
            Dim memberRoles As String()
            If req.IsAuthenticated = False Then
                memberRoles = New String() {ConfigurationManager.AppSettings("PublicRole")}
            Else
                Dim r As New Roles()
                memberRoles = r.GetRolesForUser("")
            End If

            ' check permissions: transmit file or deliver 401
            Dim folderVirtualPath As String = Path.GetDirectoryName(absolutePath).Replace("\"c, "/"c)
            Dim permissions As FileManager.FolderPermissions = FileManager.GetFolderPermissions(folderVirtualPath, memberRoles)
            If permissions And FileManager.FolderPermissions.View Then
                context.Response.ContentType = FileManager.GetContentType(fileName)
                context.Response.AddHeader("Content-Length", New FileInfo(physicalPathAndFileName).Length.ToString())
                context.Response.TransmitFile(physicalPathAndFileName)
            Else
                ' unauthorized
                context.Response.StatusCode = 401
            End If

        Else
            ' file not found
            context.Response.StatusCode = 404
        End If

        context.Response.End()

    End Sub

End Class

И web.config - и снова - это IIS7, так что вы будете использовать раздел <httpHandlers/> в разделе system.web. Я ищу любой файл в каталоге Userfiles, но думаю, что вы могли бы указать файл прямо с этим.

<system.webServer>
  <handlers>
    <add name="FileManagerFileAuthorization" path="Userfiles*" verb="GET" type="FileManagerFileAuthorization" resourceType="Unspecified" preCondition="integratedMode" />
  </handlers>
</system.webServer>

Примечание:

Чтобы разрешить .net обрабатывать файлы, отличные от .NET в IIS, необходимо разрешить процессу .net обрабатывать эти файлы. Для этого откройте диспетчер IIS, перейдите на веб-сайт и нажмите «Свойства». Перейдите на вкладку «Домашний каталог» и нажмите «Конфигурация». Добавьте сопоставление с подстановочными знаками и выберите .net dll. Если вы не уверены, скопируйте ссылку с .ascx ниже.

Поскольку это IIS6, вы не сможете использовать раздел system.webServer, описанный выше, вам нужно будет добавить обработчики http по-старому. Эта ссылка объясняет это: http://msdn.microsoft.com/en-us/library/46c5ddfy.aspx

1 голос
/ 01 июня 2011

Да, вы должны иметь возможность использовать HttpModule в своем «старом» приложении для перехвата вызовов старого CSS. В зависимости от версии IIS, установленной на вашем сервере, вам может потребоваться выполнить некоторые настройки, чтобы убедиться, что .NET обрабатывает вызовы к файлам .css, в противном случае ваш HttpModule не будет вызываться. См. этот вопрос для справки.

Как только .NET обрабатывает вызовы CSS, вы можете динамически переключать css в случае, если запрос относится к «старому» файлу css.

Вот старая статья (поскольку вы работаете в .NET 1.1), которая должна указать вам правильное направление для реализации и настройки IIS: "Перезапись URL-адресов в ASP.NET" . В основном то, что вы делаете, очень похоже, так как вы «переписываете» определенный URL (тот, что в вашем старом CSS-файле), чтобы он указывал на другой контент.

0 голосов
/ 31 июля 2011

Как я уже говорил в своем комментарии: один из ответов , я думаю, что заголовок http_referer будет указывать на страницу содержимого, которая ссылается / импортирует запрошенный файл CSS, а не на страницу результатов поиска, которая связана с страница содержания. Таким образом, даже если результаты поиска находятся на http://intranetv2, Request.ServerVariables ["HTTP_REFERER '] во время запроса файла CSS будет http://intranet, и вы продолжите получать старый файл CSS.

Похоже, вам придется найти способ либо обслуживать 10000 страниц контента из нового домена http://intranetv2, либо придумать способ установить флаг во время запроса страницы содержимого aspx может быть, в global.asax Application_BeginRequest), который может быть прочитан и обработан во время запроса файла css (HttpHandler, как предлагали другие).

Не уверен, каким будет соответствующий механизм сигнализации. Он должен работать для каждого пользователя, а не для приложения, а также быть доступным во время и сохраняться в течение нескольких разрозненных файловых запросов, и выбор ограничен использованием .NET 1.1.

0 голосов
/ 01 июня 2011

Может быть, вы можете добавить модуль HTTP в старом домене и проверить, является ли request.UrlReferrer страницей результатов поиска из нового домена, а затем заменить ссылки на старую таблицу стилей в сгенерированном выводе.

...