Request.QueryString – почему важно инкапсулировать работу c параметрами страницы?

by Dmitry [dimaka] Pavlov 18. February 2010 18:21

Любите “макароны"?

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

...
if (Request.RawUrl.ToLowerInvariant().Contains("/category/"))
{
 DisplayCategories();
}
else if (Request.RawUrl.ToLowerInvariant().Contains("/author/"))
{
 DisplayAuthors();
}
else if (Request.RawUrl.ToLowerInvariant().Contains("?tag="))
{
 DisplayTags();
}
else if (Request.QueryString["year"] != null 
    || Request.QueryString["date"] != null 
    || Request.QueryString["calendar"] != null)
{
if (Request.RawUrl.Contains("year="))
  Redirect();
 else
  DisplayDateRange();
}
else if (Request.QueryString["apml"] != null)
{
 DisplayApmlFiltering();
}
else if (Request.QueryString.Count == 0 
    || !string.IsNullOrEmpty(Request.QueryString["entry"]) 
    || !string.IsNullOrEmpty(Request.QueryString["theme"]) 
    || !string.IsNullOrEmpty(Request.QueryString["blog"]))
{
 DisplayNormal(); 
}
...

Несчастная страница пытается обработать десятки различных наборов параметров. Из десятка вызывающих страниц эти ссылки собираются также вручную. И подобная каша варится во всем веб приложении, постепенно превращая код страниц в помойку. Знакомая ситуация?

Это можно предотвратить.

И сделать это можно инкапсулировав логику по созданию и разбору строки запроса (или хотя бы параметров этого запроса) внутрь отдельного класса. Можно создать примерно такой класс для параметров конкретной страницы - назовем его PageParameters:

public class PageParameters
{
 public enum Name
 {
  Id,
  Year,
  Date
 }

 public string Id { get; set; }
 public string Year { get; set; }
 public string Date { get; set; }

 public PageParameters()
 {
  // You could add default value initialization,
 }

 public PageParameters(NameValueCollection queryString)
 {
  Id = Retrieve(queryString, Name.Id);
  Year = Retrieve(queryString, Name.Year);
  Date = Retrieve(queryString, Name.Date);
 }

 public PageParameters(string queryString)
 {

  Id = Retrieve(queryString, Name.Id);
  Year = Retrieve(queryString, Name.Year);
  Date = Retrieve(queryString, Name.Date);
 }

 private static string Retrieve(NameValueCollection queryString, 
Name parameterName) { string parameterValue = queryString[parameterName.ToString()]; if (string.IsNullOrEmpty(parameterValue)) { // You could add default value initialization, or throw the error, etc.. } return parameterValue; } public override string ToString() { // You could also add the conditions - whether to add // the parameter is it was not set or not... StringBuilder queryString = new StringBuilder(); queryString.AppendFormat("{0}={1}", Name.Id, Id); queryString.Append("&"); queryString.AppendFormat("{0}={1}", Name.Year, Year); queryString.Append("&"); queryString.AppendFormat("{0}={1}", Name.Date, Date); return queryString.ToString(); } }

Теперь - как его использовать?

На странице, которая должна уметь обрабатывать какие-то параметры рекоммендуется создавать статические методы для создания ссылки на эту страницу:

public class OnePage : System.Web.UI.Page
{
 ...

 public static string GetShortLink()
 {
  return "OnePage.aspx";
 }

 public static string GetFullLink(string id, string year, string date)
 {
  // result will be:
  // "OnePage.aspx?Id=<id>&Year=<year>&Date=<date>"
  return string.Format("{0}?{1}", GetShortLink(), 
    new PageParameters {Id = id, Year = year, Date = date});
 }

 ...
}

Там, где необходимо сегнерировать ссылку на страницу OnePage используем примерно такой код:

goOnePageHyperLink.NavigateUrl = 
    OnePage.GetFullLink("13", "2010", "18-02-2010");

Бонусы инкапсуляции параметров:

1. Мы теперь сможем не беспокоиться о поддержании имен параметров в консистентном состоянии по всему коду веб приложения.

2. Добавить все необходимые манипуляции с параметрами строки запроса в код класса PageParameters для удобства обработки вариантов запросов и повышения читаемости кода.

3. Централизовать логику разбора и составления строки запроса.

4. Избавиться от использования большого количества hard-coded строк.

Экономьте время!

Tags:

по-русски | Coding | ASP.NET

Comments

Calendar

<<  February 2012  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

View posts in large calendar