অস্তিত্ব না থাকতে পারে এমন জে টোকেনের কাছ থেকে মানটি পান (সেরা অনুশীলন)


117

JSON.NET ব্যবহার করে সি # তেও না থাকতে পারে এমন JSON মানগুলি পুনরুদ্ধার করার জন্য সেরা অনুশীলনটি কী ?

এই মুহুর্তে আমি এমন একটি জেএসএন সরবরাহকারীর সাথে কাজ করছি যা জেএসএনকে ফেরত দেয় যা মাঝে মাঝে নির্দিষ্ট কী / মান জুটি থাকে এবং কখনও কখনও তা করে না। আমি আমার মানগুলি পেতে (সম্ভবত ভুলভাবে) এই পদ্ধতিটি ব্যবহার করেছি (দ্বিগুণ হওয়ার উদাহরণ):

if(null != jToken["width"])
    width = double.Parse(jToken["width"].ToString());
else
    width = 100;

এখন এটি দুর্দান্ত কাজ করে, তবে যখন তাদের প্রচুর পরিমাণ রয়েছে তখন এটি জটিল। আমি একটি এক্সটেনশন পদ্ধতি লিখতে শেষ করেছি, এবং কেবল এটি লেখার পরে আমি ভাবছিলাম যে আমি বোকা হয়ে যাচ্ছি কিনা ... যাইহোক, এখানে এক্সটেনশন পদ্ধতিটি রয়েছে (আমি কেবল ডাবল এবং স্ট্রিংয়ের ক্ষেত্রে অন্তর্ভুক্ত করি তবে বাস্তবে আমার বেশ কয়েকটি আছে) আরো):

public static T GetValue<T>(this JToken jToken, string key,
                            T defaultValue = default(T))
{
    T returnValue = defaultValue;

    if (jToken[key] != null)
    {
        object data = null;
        string sData = jToken[key].ToString();

        Type type = typeof(T);

        if (type is double)
            data = double.Parse(sData);
        else if (type is string)
            data = sData;

        if (null == data && type.IsValueType)
            throw new ArgumentException("Cannot parse type \"" + 
                type.FullName + "\" from value \"" + sData + "\"");

        returnValue = (T)Convert.ChangeType(data, 
            type, CultureInfo.InvariantCulture);
    }

    return returnValue;
}

এবং এখানে এক্সটেনশন পদ্ধতিটি ব্যবহার করার একটি উদাহরণ রয়েছে:

width = jToken.GetValue<double>("width", 100);

বিটিডাব্লু, দয়া করে যা সত্যিই বোবা প্রশ্ন হতে পারে তা ক্ষমা করুন, যেহেতু মনে হচ্ছে এটির জন্য কোনও ফাংশন বিল্ট হওয়া উচিত ... আমি গুগল এবং জসন.এনইটি ডকুমেন্টেশন চেষ্টা করেছিলাম, তবে আমি এর সমাধান সন্ধান করতেই অক্ষম আমার প্রশ্ন বা এটি ডকুমেন্টেশনে পরিষ্কার নয়।


আমি জানি যে এটি কিছুটা দেরি হয়ে গেছে, তবে আপনি GetValueনীচের এই সরল সংস্করণটি ব্যবহার করতে চাইতে পারেন
এলবি

উত্তর:


210

জেনেরিক পদ্ধতির Value()জন্য এটি বেশ কার্যকর । আপনি যদি একে একে যুক্তযোগ্য মান ধরণের এবং ??অপারেটরের সাথে একত্রিত করেন তবে আপনি ঠিক তার আচরণটি পেতে চান :

width = jToken.Value<double?>("width") ?? 100;

4
এটি একটি এক্সটেনশন পদ্ধতি।
ডেভ ভ্যান ডেন এয়েণ্ডে

2
@ পলহাজেন, এটি তেমন খারাপ নয় ... আপনি চাকাটিকে নতুনভাবে আবিষ্কার করেছেন সব কিছু।
ডিভিনিস্ট

জেসনে "প্রস্থ" উপস্থিত না থাকলে এবং জে টোকেন নালার সাথে কাজ করে না
দীপক

2
@ প্রদীপ "প্রস্থ" উপস্থিত না থাকলে এটি কাজ করে। অবশ্যই এটা কাজ করে না যদি jTokenহয় null, কিন্তু যে কি প্রশ্ন জিজ্ঞাসা নয়। আর আপনি সহজেই যে ঠিক করতে পারবো নাল শর্তসাপেক্ষ অপারেটর ব্যবহার করে: width = jToken?.Value<double?>("width") ?? 100;
সোভিক

1
JToken.Value<T>JToken একটি JValue হলে একটি ব্যতিক্রম ছুঁড়ে
কাইল Delaney

22

আমি GetValueনীচে লিখতে হবে

public static T GetValue<T>(this JToken jToken, string key, T defaultValue = default(T))
{
    dynamic ret = jToken[key];
    if (ret == null) return defaultValue;
    if (ret is JObject) return JsonConvert.DeserializeObject<T>(ret.ToString());
    return (T)ret;
}

এইভাবে আপনি কেবলমাত্র মূল ধরণের নয় জটিল অবজেক্টগুলিরও মান পেতে পারেন। এখানে একটি নমুনা

public class ClassA
{
    public int I;
    public double D;
    public ClassB ClassB;
}
public class ClassB
{
    public int I;
    public string S;
}

var jt = JToken.Parse("{ I:1, D:3.5, ClassB:{I:2, S:'test'} }");

int i1 = jt.GetValue<int>("I");
double d1 = jt.GetValue<double>("D");
ClassB b = jt.GetValue<ClassB>("ClassB");

এটি বেশ দুর্দান্ত, তবে আমি উদ্বেগের বিচ্ছেদটি পছন্দ করি যা কেবলমাত্র সহজ ডেটা টাইপ পেয়ে আমাকে দেয়। যদিও জেএসএন পার্সিংয়ের বিষয়টি আসে সেই বিচ্ছিন্নতার ধারণাটি কিছুটা ঝাপসা। যেহেতু আমি একটি পর্যবেক্ষক / পর্যবেক্ষণযোগ্য মডেলটি প্রয়োগ করি (এমভিভিএম সহ) পাশাপাশি, আমার সমস্ত পার্সিং এক জায়গায় রাখার প্রবণতা রয়েছে এবং এটিকে সহজ রাখি (এর অংশটি আমার কাছে ফিরে আসা ডেটার অনির্দেশ্যতাও বটে)।
পল হাজেন

@ পলহাজেন আমি আপনাকে বুঝতে পারি তা বলতে পারি না। আপনার প্রশ্ন ছিল retrieving JSON values that may not even existএবং আমি প্রস্তাবিত সমস্ত ছিল আপনার GetValueপদ্ধতিটি পরিবর্তন করা change আমি মনে করি এটি আপনি যেভাবে চান তেমন কাজ করে
এলবি

আশা করি এবার আমি আরও কিছুটা পরিষ্কার হতে পারব। আপনার পদ্ধতিটি দুর্দান্ত কাজ করে এবং আমি যা চাই ঠিক তা সম্পাদন করে। যাইহোক, আমার প্রশ্নে বৃহত্তর প্রসঙ্গটি ব্যাখ্যা না করা হ'ল আমি যে বিশেষ কোডটিতে কাজ করছি তা হ'ল কোডটি আমি অত্যন্ত স্থানান্তরযোগ্য হতে চাই। যদিও এটি বিতর্কযুক্ত যে আপনার পদ্ধতিটি এই পথে চলে যায়, এটি getValue <T> থেকে অবজেক্টগুলি ডিসস্রায়াল করার দক্ষতার পরিচয় দেয়, এটি একটি কোড যা আমি আমার কোডটি এমন একটি প্ল্যাটফর্মে সরিয়ে নিতে চাই যাতে এড়াতে চান যা আরও ভাল JSON পার্সার রয়েছে (বলুন) , উইন 8 উদাহরণস্বরূপ)। সুতরাং, আমি যা চেয়েছি তার জন্য, হ্যাঁ, আপনার কোডটি নিখুঁত হবে।
পল হাজেন

9

টোকেনটি বিদ্যমান কিনা তা আপনি এখানে পরীক্ষা করতে পারেন:

if (jobject["Result"].SelectToken("Items") != null) { ... }

এটি "ফলাফল" -এ "আইটেম" বিদ্যমান কিনা তা পরীক্ষা করে।

এটি একটি কার্যকরী উদাহরণ যা ব্যতিক্রম ঘটায়:

if (jobject["Result"]["Items"] != null) { ... }

3

আপনি কেবল টাইপকাস্ট করতে পারেন এবং এটি আপনার জন্য রূপান্তরটি করবে, যেমন

var with = (double?) jToken[key] ?? 100;

nullযদি કીটি অবজেক্টে উপস্থিত না থাকে তবে এটি স্বয়ংক্রিয়ভাবে ফিরে আসবে , সুতরাং এটির জন্য পরীক্ষার দরকার নেই।


1

TYPE variable = jsonbody["key"]?.Value<TYPE>() ?? DEFAULT_VALUE;

যেমন

bool attachMap = jsonbody["map"]?.Value<bool>() ?? false;


1

এটি নালগুলির যত্ন নেয়

var body = JObject.Parse("anyjsonString");

body?.SelectToken("path-string-prop")?.ToString();

body?.SelectToken("path-double-prop")?.ToObject<double>();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.