سؤال

أنا كثيرا ما الاستفادة من 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 بدلا من ذلك إلى التخلص من كتلة حاول اللحاق:

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.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
}

وèëèé هذا هو خطر الكرمة ...

ولدي وحدة قابلة للاختبار جاف التجريد لأنه، أيضا، لأن هناك الكثير من المتغيرات سلسلة استعلام مواقع المعلومات للحفاظ على في تحويل القديمة.

ورمز أدناه هو من فئة فائدة التي منشئ يتطلب إدخال 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");
}

ملحوظة:

من الواضح أن هذا يستخدم الإحصائيات، التي لا يحبها بعض الأشخاص بسبب الطريقة التي يمكن أن تؤثر بها على كود الاختبار.يمكنك بسهولة إعادة تصميم شيء يعمل بناءً على المثيلات وأي واجهات تحتاجها.أعتقد أن مثال الإحصائيات هو الأخف.

آمل أن يساعد هذا/يعطي غذاءً للتفكير.

لدي وظائف لكل منها (في الواقع إنها فئة صغيرة واحدة، بها الكثير من الإحصائيات):

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

تقوم بإرجاع -1 إذا فشلت (وهو ما يناسبني دائمًا تقريبًا، ولدي بعض الوظائف الأخرى للأرقام السالبة أيضًا).

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

ولقد عدلت الجواب بريان واتس "بحيث إذا المعلمة غير موجود الطلب الخاص بك، وكنت قد حددت نوع قيم الفارغة فإنه سيعود لاغية:

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