Эффективное использование ASP.NET WebForms 4.0: расширение стандартных механизмов

В ASP.NET WebForms 4.0 была проделана большая работа по уменьшению зависимостей в стандартных компонентах системы. Целью разработчиков было предоставить возможность разработчикам заменять или переопределять некоторые важные компоненты системы, если это того требует.

В итоге в ASP.NET WebForms 4.0 существует возможность расширить, переопределить или заменить следующие важные механизмы:

  • механизм кеширования веб-страниц;
  • механизм валидации запросов;
  • механизм определения возможностей браузеров;
  • механизм экранирования данных и пользовательского ввода.

Ниже некоторые подробности по каждому из механизмов.

Провайдер кеширования

Начиная с первой версии ASP.NET поддерживал механизм кеширования страниц, позволяя разработчикам гибко кешировать сгенерированные страницы для повышения производительности сайта. В ASP.NET WebForms 4.0 механизм кеширования может быть эффективно переопределен пользователем. Созданные разработчиком провайдеры кеширования могут использовать любой источник для хранения кеша: диск, базу данных, удаленное хранилище, распределенные системы.

Для того, чтобы создать свой провайдер кеширования достаточно реализовать класс производный от System.Web.Caching.OutputCacheProvider. После чего вы можете зарегистрировать ваш провайдер в web.config:

 <caching>
  <outputCache defaultProvider="AspNetInternalProvider">
    <providers>
      <add name="DiskCache"
          type="Test.OutputCacheEx.DiskOutputCacheProvider, DiskCacheProvider"/>
    </providers>
  </outputCache>

</caching>

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

 <%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskCache" %>

Кроме того, вместо декларативного использования своего провайдера вы можете воспользоваться новым методом GetOuputCacheProviderName, который можно переопределить в Global.asax:

 public override string GetOutputCacheProviderName(HttpContext context)
{
    if (context.Request.Path.EndsWith("Advanced.aspx"))
       return "DiskCache";
    else
        return base.GetOutputCacheProviderName(context);
}

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

Расширение механизма валидации запросов

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

В ASP.NET 4 данный механизм был улучшен. Теперь разработчик может самостоятельно определять логику валидации запросов и более гибко реагировать на запросы разного типа. Для создания собственного механизма валидации запросов достаточно реализовать класс наследующий от System.Web.Util.RequestValidator. После этого новый механизм необходимо зарегистрировать в web.config, например так как показано ниже:

 <httpRuntime requestValidationType="Samples.MyValidator, Samples" />

Для анализа запроса разработчику доступны все необходимые данные: url, заголовки HTTP, куки и все тело запроса:

 public class CustomRequestValidation : RequestValidator
{
  protected override bool IsValidRequestString(
      HttpContext context, string value, 
      RequestValidationSource requestValidationSource, 
      string collectionKey, 
      out int validationFailureIndex) 
    {...}
 }

Базовая функциональность доступна через вызов base.IsValidRequestString.

Определение возможностей браузеров

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

Для создания собственного провайдера возможностей браузеров необходимо реализовать класс наследующий HttpCapabilitiesProvider, в котором переопределить метод GetBrowserCapabilities:

 public class CustomProvider : HttpCapabilitiesProvider 
 { 
          public override HttpBrowserCapabilities 
          GetBrowserCapabilities(HttpRequest request) 
          { 
            HttpBrowserCapabilities browserCaps = new HttpBrowserCapabilities(); 
            Hashtable values = new Hashtable(180, StringComparer.OrdinalIgnoreCase); 
            values[String.Empty] = request.UserAgent; 
            values["browser"] = "MyCustomBrowser"; 
            browserCaps.Capabilities = values; 
            return browserCaps;
          } 
 }

Созданный тип необходимо зарегистрировать в web.config:

 <system.web> 
    <browserCaps provider="ClassLibrary2.CustomProvider, ClassLibrary2, Version=1.0.0.0, Culture=neutral" /> 
</system.web>

Существует другой путь регистрации провайдера через явное указание в коде события Application_Start в Global.asax:

 void Application_Start(object sender, EventArgs e) 
{ 
  HttpCapabilitiesBase.BrowserCapabilitiesProvider =
    new ClassLibrary2.CustomProvider();
   // ... 
 }

Расширение механизма экранирования вывода данных

Последний механизм, который будет рассмотрен в рамках этой статьи – это механизм расширения экранирования вывода данных. В ASP.NET 4 вы можете воспользоваться переопределением экранирования данных, для того, чтобы реализовать свой эффективный способ защиты от потенциально опасных данных. Для пользовательского переопределения экранирования доступны следующие данные:

  • HTML-экранирование;
  • URL-декодирование;
  • экранирование атрибутов HTML;
  • экранирование HTTP-заголовков.

Вы можете определить свой провайдер с помощью класса наследующего от System.Web.Util.HttpEncoder. После создания класса, перед использованием, его необходимо зарегистрировать в web.config:

 <httpRuntime encoderType="Samples.MyCustomEncoder, Samples" />

После того, как пользовательский механизм экранирования переопределен, система ASP.NET будет использовать его по умолчанию, заменяя вызовы методов System.Web.HttpUtility или System.Web.HttpServerUtility новым функционалом.