Подтвердить что ты не робот

Преобразование/доступ к значениям QueryString в ASP.NET

Мне любопытно, что все делают для обработки/абстрагирования QueryString в ASP.NET. В некоторых наших веб-приложениях я вижу много всего по всему сайту:

int val = 0;
if(Request.QueryString["someKey"] != null)
{
val = Convert.ToInt32(Request.QueryString["someKey"]);
}

Каковы некоторые лучшие способы справиться с этой грубостью?

4b9b3361

Ответ 1

Мне нравится идея абстрагирования их как свойств. Например:

        public int age { 
        get
        {
            if (Request.QueryString["Age"] == null)
                return 0;
            else
                return int.Parse(Request.QueryString["Age"]);                                    
        }
    }

Вы можете добавить дополнительную проверку, если хотите. Но я, как правило, люблю обматывать все мои переменные строки запроса таким образом.

EDIT: --- Также как еще один плакат указал, что вы должны создавать эти свойства на каждой странице. Мой ответ - нет. Вы можете создать эти свойства в одном классе, который вы можете назвать "QueryStrings" или что-то еще. Затем вы можете создать экземпляр этого класса на каждой странице, где вы хотите получить доступ к строкам запроса, тогда вы можете просто сделать что-то вроде

var queryStrings = new QueryStrings();
var age = queryStrings.age;

Таким образом вы можете инкапсулировать всю логику для доступа и обработки каждого типа переменной запроса в одном обслуживаемом месте.

EDIT2: --- И поскольку это экземпляр класса, вы также можете использовать инъекцию зависимостей для инъекции класса QueryStrings во всех местах, где вы его используете. StructureMap хорошо справляется с этим. Это также позволяет вам макетировать класс QueryStrings и вводить это, если вы хотите выполнить автоматическое модульное тестирование. Это намного проще обмануть, чем объект ASP.Net Request.

Ответ 2

Одно дело, что вы не записываете пустые значения здесь. У вас может быть URL-адрес " http://example.com?someKey=&anotherKey=12345", и в этом случае значение параметра "someKey" равно "" (пусто). Вы можете использовать string.IsNullOrEmpty() для проверки как нулевого, так и пустого состояний.

Я также изменил бы "someKey", который будет храниться в переменной. Таким образом, вы не повторяете буквальные строки в нескольких местах. Это упрощает обслуживание.

int val = 0;
string myKey = "someKey";
if (!string.IsNullOrEmpty(Request.QueryString[myKey]))
{
    val = int.Parse(Request.QueryString[myKey]);
}

Я надеюсь, что это поможет!

Ян

Ответ 3

Напишите какой-то вспомогательный метод (библиотека), чтобы обработать его...

public static void GetInt(this NameValueCollection nvCol, string key, out int keyValue, int defaultValue)
{
    if (string.IsNullOrEmpty(nvCol[key]) || !int.TryParse(nvCol[key], out keyValue))
        keyValue = defaultValue;
}

Или что-то в этом роде...

Ответ 4

Вот что я придумал. Он использует generics для возврата строго типизированного значения из QueryString или необязательного значения по умолчанию, если параметр не находится в QueryString:

/// <summary>
    /// Gets the given querystring parameter as a the specified value <see cref="Type"/>
    /// </summary>
    /// <typeparam name="T">The type to convert the querystring value to</typeparam>
    /// <param name="name">Querystring parameter name</param>
    /// <param name="defaultValue">Default value to return if parameter not found</param>
    /// <returns>The value as the specified <see cref="Type"/>, or the default value if not found</returns>
    public static T GetValueFromQueryString<T>(string name, T defaultValue) where T : struct
    {
        if (String.IsNullOrEmpty(name) || HttpContext.Current == null || HttpContext.Current.Request == null)
            return defaultValue;

        try
        {
            return (T)Convert.ChangeType(HttpContext.Current.Request.QueryString[name], typeof(T));
        }
        catch
        {
            return defaultValue;
        }
    }

    /// <summary>
    /// Gets the given querystring parameter as a the specified value <see cref="Type"/>
    /// </summary>
    /// <typeparam name="T">The type to convert the querystring value to</typeparam>
    /// <param name="name">Querystring parameter name</param>
    /// <returns>The value as the specified <see cref="Type"/>, or the types default value if not found</returns>
    public static T GetValueFromQueryString<T>(string name) where T : struct
    {
        return GetValueFromQueryString(name, default(T));
    }

С момента написания этого сообщения я написал очень маленькую библиотеку классов для управления значениями запроса (см. https://github.com/DanDiplo/QueryString-Helper

Ответ 5

Мы использовали константы для хранения всех этих "свободных" ключей в центральном месте:

public class Constants
{
  public class QueryString
  {
    public const string PostID = "pid";
    public const string PostKey = "key";
  }
  public class Cookie
  {
    public const string UserID = "mydomain.com-userid";
  }
  public class Cache
  {
    public const string PagedPostList = "PagedPostList-{0}-{1}";
  }
  public class Context
  {
    public const string PostID = "PostID";
  }
  public class Security
  {
    public const RoleAdministrator = "Administrator";
  }
}

Таким образом, вы легко получаете доступ к константам, которые вам нужны:

public void Index()
{
  if (Request[Constants.QueryString.PostKey] == "eduncan911")
  {
    // do something
  }
}

public object GetPostsFromCache(int postID, int userID)
{
  String cacheKey = String.Format(
      Constants.Cache.PagedPostList
      , userID
      , postID);
  return Cache[cacheKey] as IList<Post>;
}

Ответ 6

По мне, лучший способ получить значение querystring выглядит следующим образом:
Если запрос не найден, значение val будет 0.

int val = 0;
int.TryParse(Request.QueryString["someKey"], out val);

Ответ 7

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

Если у вас много страниц, добавление свойств для каждого из них может быть более трудоемким, чем того стоит. Но это, очевидно, просто предпочтение, поэтому каждому его/ее.

Одна интересная вещь, которую вы могли бы улучшить в другом методе помощника по постерам, заключается в том, чтобы вместо параметра out указать ссылочный параметр (смените на ref). Таким образом вы можете установить значение по умолчанию для свойства, если оно не передано. Иногда вам могут понадобиться дополнительные параметры, например, тогда вы можете начать с некоторого значения по умолчанию для тех случаев, когда необязательный параметр явно не передается (проще, чем значение по умолчанию передается отдельно). Вы даже можете добавить логический параметр IsRequired в конце и заставить его генерировать исключение, если для bool установлено значение true и параметр не передан. Это может быть полезно во многих случаях.