문제

나는 자주 사용합니다 Request.QueryString[] 변수.

Page_load 나는 종종 다음과 같은 일을한다.

       int id = -1;

        if (Request.QueryString["id"] != null) {
            try
            {
                id = int.Parse(Request.QueryString["id"]);
            }
            catch
            {
                // deal with it
            }
        }

        DoSomethingSpectacularNow(id);

그것은 모두 약간 어리 석고 쓰레기처럼 보입니다. 당신은 당신을 어떻게 처리합니까? Request.QueryString[]에스?

도움이 되었습니까?

해결책

아래는 다음과 같은 코드를 쓸 수있는 확장 방법입니다.

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);
}

다른 팁

대신 int.tryparse를 사용하여 Try-Catch 블록을 제거하십시오.

if (!int.TryParse(Request.QueryString["id"], out id))
{
  // error case
}

이 친구 해보세요 ...

List<string> keys = new List<string>(Request.QueryString.AllKeys);

그러면 당신은 그 남자를 현악기를 찾을 수 있습니다.

keys.Contains("someKey")

작은 도우미 방법을 사용하고 있습니다.

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);

int.rityparse를 대신 사용하는 것은 ...

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 이것은 업장 위험입니다 ...

레거시 변환을 유지하기에는 너무 많은 쿼리 스트링 변수가 있었기 때문에 건조 단위 테스트 가능한 추상화가 있습니다.

아래 코드는 생성자가 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;
}

실제로 제네릭을 사용하여 "랩"세션을 사용하는 유틸리티 클래스가 있습니다.이 세션은 모든 "Grunt Work"를 수행합니다. 또한 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");
}

노트:

이것은 분명히 테스트 코드에 영향을 줄 수있는 방식으로 인해 마음에 들지 않는 통계를 사용합니다. 인스턴스와 필요한 인터페이스를 기반으로 작동하는 무언가로 쉽게 리팩토링 할 수 있습니다. 가장 가벼운.

이것이 생각할 수 있도록 도움이되기를 바랍니다.

나는 각각에 대한 기능을 가지고 있습니다 (실제로는 많은 정적이 포함 된 하나의 작은 클래스입니다).

  • GetIntegerFromQuerystring(val)
  • GetIntegerFromPost(val)
  • ....

실패하면 -1을 반환합니다 (거의 항상 괜찮습니다. 네 숫자에 대한 다른 기능도 있습니다.).

Dim X as Integer = GetIntegerFromQuerystring("id")
If x = -1 Then Exit Sub

Bryan Watts의 답변을 수정하여 귀하의 요청 매개 변수가 존재하지 않고 Nullable 유형을 지정하면 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;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top