Ниже дополнительный метод, который позволит Вам писать код как это:
int id = request.QueryString.GetValue<int>("id");
DateTime date = request.QueryString.GetValue<DateTime>("date");
Это использует TypeDescriptor
для выполнения преобразования. На основе Ваших потребностей Вы могли добавить перегрузку, которая берет значение по умолчанию вместо того, чтобы выдать исключение:
public static T GetValue<T>(this NameValueCollection collection, string key)
{
if(collection == null)
{
throw new ArgumentNullException("collection");
}
var value = collection[key];
if(value == null)
{
throw new ArgumentOutOfRangeException("key");
}
var converter = TypeDescriptor.GetConverter(typeof(T));
if(!converter.CanConvertFrom(typeof(string)))
{
throw new ArgumentException(String.Format("Cannot convert '{0}' to {1}", value, typeof(T)));
}
return (T) converter.ConvertFrom(value);
}
Используйте интервал. TryParse вместо этого для избавлений от блока try-catch:
if (!int.TryParse(Request.QueryString["id"], out id))
{
// error case
}
Я использую немного вспомогательного метода:
public static int QueryString(string paramName, int defaultValue)
{
int value;
if (!int.TryParse(Request.QueryString[paramName], out value))
return defaultValue;
return value;
}
Этот метод позволяет мне читать значения из строки запроса следующим образом:
int id = QueryString("id", 0);
Хорошо, с одной стороны, используйте интервал. TryParse вместо этого...
int id;
if (!int.TryParse(Request.QueryString["id"], out id))
{
id = -1;
}
, Который предполагает, что "не подарок" должен иметь тот же результат как "не целое число", конечно.
РЕДАКТИРОВАНИЕ: В других случаях, когда Вы собираетесь использовать параметры запроса в качестве строк так или иначе, я думаю, что это - определенно хорошая идея проверить это, они присутствуют.
Вы можете использовать дополнительные методы ниже также и действительно любите это
int? id = Request["id"].ToInt();
if(id.HasValue)
{
}
//Дополнительные методы
public static int? ToInt(this string input)
{
int val;
if (int.TryParse(input, out val))
return val;
return null;
}
public static DateTime? ToDate(this string input)
{
DateTime val;
if (DateTime.TryParse(input, out val))
return val;
return null;
}
public static decimal? ToDecimal(this string input)
{
decimal val;
if (decimal.TryParse(input, out val))
return val;
return null;
}
if(!string.IsNullOrEmpty(Request.QueryString["id"]))
{
//querystring contains id
}
Eeee это - риск кармы...
у меня есть DRY тестируемая единицей абстракция потому что, ну, в общем, потому что было слишком много querystring переменных для продолжения в преобразовании прежней версии.
код ниже от служебного класса, конструктор которого требует, чтобы NameValueCollection ввел (this.source), и массив строк "ключи" - то, потому что приложение прежней версии было довольно органическим и разработало возможность для нескольких различных строк, чтобы быть потенциальным входным ключом. Однако мне отчасти нравится расширяемость. Этот метод осматривает набор для ключа и возвращает его в требуемом типе данных.
private T GetValue<T>(string[] keys)
{
return GetValue<T>(keys, default(T));
}
private T GetValue<T>(string[] keys, T vDefault)
{
T x = vDefault;
string v = null;
for (int i = 0; i < keys.Length && String.IsNullOrEmpty(v); i++)
{
v = this.source[keys[i]];
}
if (!String.IsNullOrEmpty(v))
{
try
{
x = (typeof(T).IsSubclassOf(typeof(Enum))) ? (T)Enum.Parse(typeof(T), v) : (T)Convert.ChangeType(v, typeof(T));
}
catch(Exception e)
{
//do whatever you want here
}
}
return x;
}
У меня на самом деле есть служебный класс, который использует Дженерики для "обертывания" сессии, которая делает всю "трудную работу" для меня, у меня также есть что-то почти идентичное для работы со значениями QueryString.
Это помогает удалить простофилю кода для (часто многочисленный) проверки..
, Например:
public class QueryString
{
static NameValueCollection QS
{
get
{
if (HttpContext.Current == null)
throw new ApplicationException("No HttpContext!");
return HttpContext.Current.Request.QueryString;
}
}
public static int Int(string key)
{
int i;
if (!int.TryParse(QS[key], out i))
i = -1; // Obviously Change as you see fit.
return i;
}
// ... Other types omitted.
}
// And to Use..
void Test()
{
int i = QueryString.Int("test");
}
ПРИМЕЧАНИЕ:
Это, очевидно, использует помехи, которые некоторые люди не любят из-за способа, которым это может код испытания на удар.. Можно легко осуществить рефакторинг во что-то, что работает на основе экземпляров и любых интерфейсов, которых Вы требуете.. Я просто думаю, что статический пример является самым легким.
Hope это помогает/дает пище для размышления.
У меня действительно есть функции для каждого (на самом деле, это - один маленький класс с большим количеством помех):
GetIntegerFromQuerystring(val)
GetIntegerFromPost(val)
....
Это возвращается-1, если сбои (, который почти всегда хорошо для меня, у меня есть некоторые другие функции для отрицательных чисел также ).
Dim X as Integer = GetIntegerFromQuerystring("id")
If x = -1 Then Exit Sub
Я изменил ответ Брайана Уоттса так, что если параметр, который вы запрашиваете, не существует и вы указали тип, допускающий значение NULL, он вернет null:
public static T GetValue<T>(this NameValueCollection collection, string key)
{
if (collection == null)
{
return default(T);
}
var value = collection[key];
if (value == null)
{
return default(T);
}
var type = typeof(T);
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = Nullable.GetUnderlyingType(type);
}
var converter = TypeDescriptor.GetConverter(type);
if (!converter.CanConvertTo(value.GetType()))
{
return default(T);
}
return (T)converter.ConvertTo(value, type);
}
Теперь вы можете сделать это:
Request.QueryString.GetValue<int?>(paramName) ?? 10;