JSON.NET ব্যবহার করে সি # তে জেএসএন ডেটা বিহীন করা


144

আমি সি # এবং জেএসএন ডেটা নিয়ে কাজ করার তুলনায় তুলনামূলকভাবে নতুন এবং দিকনির্দেশ খুঁজছি। আমি .NET3.5SP1 এবং JSON.NET 3.5r6 দিয়ে সি # 3.0 ব্যবহার করছি।

আমার একটি সংজ্ঞায়িত সি # ক্লাস রয়েছে যা আমার একটি জেএসওএন কাঠামো থেকে পপুলেশন করা দরকার। তবে, ওয়েব পরিষেবা থেকে পুনরুদ্ধার করা কোনও এন্ট্রির জন্য প্রতিটি জেএসএন কাঠামোতে সি # শ্রেণির মধ্যে সংজ্ঞায়িত সমস্ত সম্ভাব্য বৈশিষ্ট্য নেই।

আমি যা করছি তা ভুল, শক্ত উপায়ে মনে হচ্ছে যা করছি এবং জওবজেক্ট থেকে প্রতিটি মান একে একে বেছে নেওয়া এবং স্ট্রিংটিকে পছন্দসই শ্রেণীর সম্পত্তিতে রূপান্তর করা।

JsonSerializer serializer = new JsonSerializer();
var o = (JObject)serializer.Deserialize(myjsondata);

MyAccount.EmployeeID = (string)o["employeeid"][0];

জেএসএন কাঠামোকে সি # শ্রেণিতে ডিজিটালাইজ করার এবং জেএসএন উত্স থেকে সম্ভাব্য নিখোঁজ ডেটা হ্যান্ডেল করার সর্বোত্তম উপায় কী?

আমার শ্রেণি হিসাবে সংজ্ঞায়িত করা হয়:

  public class MyAccount
  {

    [JsonProperty(PropertyName = "username")]
    public string UserID { get; set; }

    [JsonProperty(PropertyName = "givenname")]
    public string GivenName { get; set; }

    [JsonProperty(PropertyName = "sn")]
    public string Surname { get; set; }

    [JsonProperty(PropertyName = "passwordexpired")]
    public DateTime PasswordExpire { get; set; }

    [JsonProperty(PropertyName = "primaryaffiliation")]
    public string PrimaryAffiliation { get; set; }

    [JsonProperty(PropertyName = "affiliation")]
    public string[] Affiliation { get; set; }

    [JsonProperty(PropertyName = "affiliationstatus")]
    public string AffiliationStatus { get; set; }

    [JsonProperty(PropertyName = "affiliationmodifytimestamp")]
    public DateTime AffiliationLastModified { get; set; }

    [JsonProperty(PropertyName = "employeeid")]
    public string EmployeeID { get; set; }

    [JsonProperty(PropertyName = "accountstatus")]
    public string AccountStatus { get; set; }

    [JsonProperty(PropertyName = "accountstatusexpiration")]
    public DateTime AccountStatusExpiration { get; set; }

    [JsonProperty(PropertyName = "accountstatusexpmaxdate")]
    public DateTime AccountStatusExpirationMaxDate { get; set; }

    [JsonProperty(PropertyName = "accountstatusmodifytimestamp")]
    public DateTime AccountStatusModified { get; set; }

    [JsonProperty(PropertyName = "accountstatusexpnotice")]
    public string AccountStatusExpNotice { get; set; }

    [JsonProperty(PropertyName = "accountstatusmodifiedby")]
    public Dictionary<DateTime, string> AccountStatusModifiedBy { get; set; }

    [JsonProperty(PropertyName = "entrycreatedate")]
    public DateTime EntryCreatedate { get; set; }

    [JsonProperty(PropertyName = "entrydeactivationdate")]
    public DateTime EntryDeactivationDate { get; set; }

  }

এবং পার্স করার জন্য জেএসএনের একটি নমুনা হ'ল:

{
    "givenname": [
        "Robert"
    ],
    "passwordexpired": "20091031041550Z",
    "accountstatus": [
        "active"
    ],
    "accountstatusexpiration": [
        "20100612000000Z"
    ],
    "accountstatusexpmaxdate": [
        "20110410000000Z"
    ],
    "accountstatusmodifiedby": {
        "20100214173242Z": "tdecker",
        "20100304003242Z": "jsmith",
        "20100324103242Z": "jsmith",
        "20100325000005Z": "rjones",
        "20100326210634Z": "jsmith",
        "20100326211130Z": "jsmith"
    },
    "accountstatusmodifytimestamp": [
        "20100312001213Z"
    ],
    "affiliation": [
        "Employee",
        "Contractor",
        "Staff"
    ],
    "affiliationmodifytimestamp": [
        "20100312001213Z"
    ],
    "affiliationstatus": [
        "detached"
    ],
    "entrycreatedate": [
        "20000922072747Z"
    ],
    "username": [
        "rjohnson"
    ],
    "primaryaffiliation": [
        "Staff"
    ],
    "employeeid": [
        "999777666"
    ],
    "sn": [
        "Johnson"
    ]
}

উত্তর:


277

ব্যবহার

var rootObject =  JsonConvert.DeserializeObject<RootObject>(string json);

JSON 2 C # তে আপনার ক্লাস তৈরি করুন


জসন.এনইটি ডকুমেন্টেশন: জেসন.এনইটের সাথে জেএসওনকে সিরিয়ালাইজিং এবং ডিসরিয়ালাইজ করছে


32
ভিজ্যুয়াল স্টুডিওতে সম্পাদনা-পেস্ট বিশেষ মেনুতে ক্লাস বিকল্প হিসাবে একটি পেস্ট জেএসওএনও রয়েছে।
জোনাথন অ্যালেন

76

আপনি কি জেনেরিক DeserializeObject পদ্ধতিটি ব্যবহার করার চেষ্টা করেছেন?

JsonConvert.DeserializeObject<MyAccount>(myjsondata);

জেএসওএন ডেটাতে যে কোনও অনুপস্থিত ক্ষেত্রকে কেবল নূলে রাখা উচিত।

হালনাগাদ:

যদি JSON স্ট্রিংটি একটি অ্যারে হয় তবে এটি ব্যবহার করে দেখুন:

var jarray = JsonConvert.DeserializeObject<List<MyAccount>>(myjsondata);

jarrayতারপর একটি হতে হবে List<MyAccount>

অন্য আপডেট:

আপনি যে ব্যতিক্রমটি পাচ্ছেন তা অবজেক্টের অ্যারের সাথে সামঞ্জস্যপূর্ণ নয় I আমি মনে করি সিরিয়ালাইজারটি আপনার অভিধান-টাইপ করা accountstatusmodifiedbyসম্পত্তিতে সমস্যা করছে।

accountstatusmodifiedby সিরিয়ালাইজেশন থেকে সম্পত্তি বাদ দেওয়ার চেষ্টা করুন এবং দেখুন এটি সাহায্য করে কিনা। যদি এটি হয় তবে আপনার সেই সম্পত্তিটি অন্যভাবে উপস্থাপন করার প্রয়োজন হতে পারে।

ডকুমেন্টেশন: জেসন.এনইটি দিয়ে জেএসওনকে সিরিয়ালাইজিং এবং ডিজিজারাইজ করছে


ধন্যবাদ। তবে আমি "JSON অ্যারে ডিজিটালাইজ করতে পারি না 'টাইপ করে' সিস্টেম.স্ট্রিং 'এর ত্রুটি পেয়েছি।" যখন এটি ডিজনিয়ালাইজ করার চেষ্টা করছে (উদাহরণস্বরূপ) জেএসওএন প্রদত্ত নাম অ্যারেটিকে বর্গননেম স্ট্রিংয়ে শ্রেণি দেয়। আমি সি # শ্রেণিতে স্ট্রিং হিসাবে যে JSON বৈশিষ্ট্যগুলি সংজ্ঞায়িত করেছি তা কেবলমাত্র একক উপাদান অ্যারে হয় are এই কারণেই deserialize প্রক্রিয়া চলাকালীন আমি এই ধরণের ইস্যুতে দৌড়ে যাওয়ার পরে একে একে মানগুলি বাছাই শুরু করেছি। অন্য যাদু যে আমি উপেক্ষা করছি?

সুতরাং ... DateTime AccountStatusExpiration(উদাহরণস্বরূপ) কোডে সংজ্ঞায়িত হিসাবে নমনীয় নয়। এটি অবিচল করতে কী লাগবে? কেবলমাত্র পরিবর্তন DateTimeকরতে DateTime??
হামিশ গ্রুবিজন

50

উত্তরটি https://stackoverflow.com/a/10718128/776476 থেকে পুনরুত্পাদন করা হয়েছে

dynamicজিনিসগুলি সহজ করতে আপনি সি # টাইপ ব্যবহার করতে পারেন । এই কৌশলটি পুনরায় ফ্যাক্টরিংকে আরও সহজ করে তোলে কারণ এটি যাদু-স্ট্রিংয়ের উপর নির্ভর করে না।

JSON

jsonনিচে স্ট্রিং একটি HTTP API কল থেকে একটি সহজ প্রতিক্রিয়া হয় এবং এটি দুই বৈশিষ্ট করবেঃ Idএবং Name

{"Id": 1, "Name": "biofractal"}

সি শার্প

JsonConvert.DeserializeObject<dynamic>()এই স্ট্রিংটিকে একটি ডায়নামিক টাইপের ডিজিজায়ালাইজ করতে ব্যবহার করুন তারপরে সাধারণ উপায়ে কেবল তার বৈশিষ্ট্যগুলিতে অ্যাক্সেস করুন।

var results = JsonConvert.DeserializeObject<dynamic>(json);
var id = results.Id;
var name= results.Name;

দ্রষ্টব্য : নিউটনসফট সমাবেশের নিউগেট লিঙ্কটি হ'ল http://nuget.org/packages/newtonsoft.json । যোগ করতে ভুলবেন না: using Newtonsoft.Json;এই ক্লাসে অ্যাক্সেস করতে।


7
<অভিনব> এর ব্যবহার পছন্দ করুন। যাইহোক, এটি কাজ করার জন্য আমাকে এটি করতে হয়েছিল: ফলাফল ["আইডি"]
Val

1
যদিও গতিশীল একটি দুর্দান্ত বিকল্প, উপরের উদাহরণগুলি 'ম্যাজিক স্ট্রিংস' ব্যবহার করছে না বরং এর পরিবর্তে দৃ strongly়ভাবে টাইপযুক্ত জেনেরিকগুলি ব্যবহার করছে যা সাধারণ ভিএস রিফ্যাক্টরিং কৌশলগুলির সময় আপডেট করা হয় (যদি এমভিসিতে কোনও ভিউ না থাকে যা এই প্রশ্নের ক্ষেত্রের বাইরে থাকে)।
gcoleman0828

4
আপনার এখনও 'ম্যাজিক স্ট্রিংস' রয়েছে, এগুলি এখন ডায়নামিকের ব্যবহার দ্বারা লুকিয়ে রয়েছে!
ইয়ান রিংরোজ

@ আয়ানরিঙ্গরোজের পয়েন্টটি যেমন প্রকাশ করেছে, জৈবফ্রাক্টাল এর পিছনে পিছনে "ম্যাজিক স্ট্রিংস" রয়েছে। ডায়নামিক অবজেক্টটি ফেরত দিয়েছিল DeserializeObject<dynamic>সংজ্ঞা অনুসারে "টাইপ-চেকড" নয়। সুতরাং নিম্নলিখিত লাইনগুলি results.Idএবং results.Nameসংকলন সময়ে যাচাই করা যাবে না। পরিবর্তে রান-টাইমে কোনও ত্রুটি ঘটবে। দৃ strongly়-টাইপযুক্ত কল যেমন এর সাথে এটির বিপরীতে করুন DeserializeObject<List<MyAccount>>। সংকলন সময়ে এই বৈশিষ্ট্যগুলির উল্লেখগুলি নিশ্চিত করা যেতে পারে। এর ব্যবহার dynamicযদিও এটি সুবিধাজনক হতে পারে তবে সম্পত্তির নাম হিসাবে "ম্যাজিক স্ট্রিংস" প্রবর্তন করে; দৃ rob়তা হ্রাস IMHO।
টুলমেকারস্টেভ

8

তুমি ব্যবহার করতে পার:

JsonConvert.PopulateObject(json, obj);

এখানে: jsonজেসন স্ট্রিং, objলক্ষ্য বস্তু। দেখুন: উদাহরণ

দ্রষ্টব্য: PopulateObject()পরে আপত্তিগুলির তালিকার ডেটা মুছবে নাPopulate() , obj'sতালিকার সদস্যটিতে জসন স্ট্রিং থেকে তার মূল ডেটা এবং ডেটা থাকবে


2
এটি পপুলেটবজেক্ট - পপুলেট অবজেক্ট মডেলে নেই।
amok

1
এটি আমার জন্য নিখুঁতভাবে কাজ করেছে! আমার বেশ জটিল জেসন স্ট্রিং ছিল এমন সমস্যা ছিল যখন আমি যখন এটি সি # অবজেক্টে কাস্ট করার চেষ্টা করতাম তখন 'নটনুল' হিসাবে চিহ্নিত কোনও কিছুই সেই বস্তুটি থেকে অনুপস্থিত হবে, যদিও এটি জেএসএন স্ট্রিংয়ের সাথে শুরু হওয়ার সাথে উপস্থিত ছিল। খুব অদ্ভুত. আমি এই পদ্ধতিটি ব্যবহার করেছি এবং এটি নিখুঁতভাবে কাজ করেছে!
jward01

3

বব্যান্টের জবাব বন্ধ করে দেওয়া, এটি কোনও দূরবর্তী URL থেকে জেএসএনকে ডিসিজায়ালাইজ করার জন্য আমার সম্পূর্ণ সমাধান।

using Newtonsoft.Json;
using System.Net.Http;

namespace Base
{
    public class ApiConsumer<T>
    {
        public T data;
        private string url;

        public CalendarApiConsumer(string url)
        {
            this.url = url;
            this.data = getItems();
        }

        private T getItems()
        {
            T result = default(T);
            HttpClient client = new HttpClient();

            // This allows for debugging possible JSON issues
            var settings = new JsonSerializerSettings
            {
                Error = (sender, args) =>
                {
                    if (System.Diagnostics.Debugger.IsAttached)
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                }
            };

            using (HttpResponseMessage response = client.GetAsync(this.url).Result)
            {
                if (response.IsSuccessStatusCode)
                {
                    result = JsonConvert.DeserializeObject<T>(response.Content.ReadAsStringAsync().Result, settings);
                }
            }
            return result;
        }
    }
}

ব্যবহারের মত হবে:

ApiConsumer<FeedResult> feed = new ApiConsumer<FeedResult>("http://example.info/feeds/feeds.aspx?alt=json-in-script");

জ্যামাসফট জেএসএন ক্লাস জেনারেটরFeedResult ব্যবহার করে ক্লাসটি কোথায় তৈরি করা হয়েছে

আমি যে সেটিংস ব্যবহার করেছি সেগুলির একটি স্ক্রিনশট এখানে দেওয়া হয়েছে, ওয়েব সংস্করণ যার জন্য অ্যাকাউন্ট না করতে পারে এমন অদ্ভুত সম্পত্তি নামের জন্য অনুমতি দেয় ।

জ্যামাসফট জেএসএন ক্লাস জেনারেটর


1

আমি খুঁজে পেয়েছি যে আমি আমার অবজেক্টটি ভুলভাবে তৈরি করেছি। আমি জেএসএন থেকে আমার অবজেক্ট শ্রেণি তৈরি করতে http://json2csharp.com/ ব্যবহার করেছি। একবার আমার কাছে সঠিক ওজেক্ট থাকলে আমি ইস্যু ছাড়াই কাস্ট করতে সক্ষম হয়েছি। নরবিত, নুব ভুল ভেবেছিলাম আপনার যদি একই সমস্যা থাকে তবে আমি এটি যুক্ত করব।


1

আরও তথ্যের জন্য আপনি কয়েকটি শ্রেণীর জেনারেটর অনলাইনে পরীক্ষা করে দেখতে পারেন। তবে আমি বিশ্বাস করি যে উত্তরগুলির কয়েকটি কার্যকর হয়েছে। এখানে আমার পদ্ধতির যা কার্যকর হতে পারে's

নিম্নলিখিত কোডটি একটি গতিশীল পদ্ধতি মাথায় রেখে তৈরি করা হয়েছিল।

dynObj = (JArray) JsonConvert.DeserializeObject(nvm);

foreach(JObject item in dynObj) {
 foreach(JObject trend in item["trends"]) {
  Console.WriteLine("{0}-{1}-{2}", trend["query"], trend["name"], trend["url"]);
 }
}

এই কোডটি মূলত আপনাকে জসন স্ট্রিংয়ে থাকা সদস্যদের অ্যাক্সেস করার অনুমতি দেয়। ক্লাসের প্রয়োজন ছাড়াই অন্যরকম উপায়। query, trendএবংurl জসন স্ট্রিংয়ে থাকা অবজেক্টগুলি।

আপনি এই ওয়েবসাইটটি ব্যবহার করতে পারেন । ক্লাসগুলিকে 100% বিশ্বাস করবেন না তবে আপনি ধারণাটি পাবেন।


0

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

এটি একটি পুরানো পোস্ট, তবে সমস্যাগুলি নোট করতে চেয়েছিল।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.