146

私は C# と JSON データの操作に比較的慣れていないため、ガイダンスを求めています。私は C# 3.0 と .NET3.5SP1、および JSON.NET 3.5r6 を使用しています。

JSON 構造から入力する必要がある定義済みの C# クラスがあります。ただし、Web サービスから取得されたエントリのすべての JSON 構造に、C# クラス内で定義されている可能性のあるすべての属性が含まれているわけではありません。

私は、間違った難しい方法と思われることを行っていて、JObject から各値を 1 つずつ選択し、文字列を目的のクラス プロパティに変換しています。

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

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

JSON 構造を C# クラスに逆シリアル化し、JSON ソースから欠落している可能性のあるデータを処理する最良の方法は何ですか?

私のクラスは次のように定義されています。

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

  }

解析する JSON のサンプルは次のとおりです。

{
    "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"
    ]
}
4

7 に答える 7

285

使用する

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

JSON 2 C#でクラスを作成する


Json.NETドキュメント:Json.NETを使用したJSONのシリアル化と逆シリアル化

于 2012-01-27T18:36:35.043 に答える
79

一般的な DeserializeObject メソッドを使用してみましたか?

JsonConvert.DeserializeObject<MyAccount>(myjsondata);

JSON データに欠落しているフィールドは、単純に NULL のままにしておく必要があります。

アップデート:

JSON 文字列が配列の場合は、これを試してください。

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

jarrayである必要がありList<MyAccount>ます。

別の更新:

accountstatusmodifiedby取得している例外は、オブジェクトの配列と一致していません。シリアライザーが Dictionary 型のプロパティに問題があると思います。

シリアル化からプロパティを除外してみてaccountstatusmodifiedby 、それが役立つかどうかを確認してください。その場合、そのプロパティを別の方法で表現する必要がある場合があります。

ドキュメント: Json.NET を使用した JSON のシリアライズとデシリアライズ

于 2010-03-30T15:03:26.097 に答える
8

以下を使用できます。

JsonConvert.PopulateObject(json, obj);

ここで:jsonは json 文字列、objはターゲット オブジェクトです。参照:

注:PopulateObject()は obj のリスト データを消去しません。その後Populate()obj'sリスト メンバーには元のデータと json 文字列からのデータが含まれます。

于 2011-12-22T16:25:29.863 に答える
3

bbant の回答に基づいて作成された、これはリモート URL から JSON を逆シリアル化するための完全なソリューションです。

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

Xamasoft JSON Class GeneratorFeedResultを使用して生成されたクラスはどこにありますか

これは私が使用した設定のスクリーンショットで、Web バージョンでは説明できなかった奇妙なプロパティ名を許可しています。

Xamasoft JSON クラス ジェネレーター

于 2014-07-31T15:58:01.810 に答える
-1

サンプル データが正しいと仮定すると、指定された名前、および角かっこで囲まれたその他のエントリは JS の配列です...これらのデータ型には List を使用する必要があります。そして、たとえばaccountstatusexpmaxdateのリスト...あなたの例では日付が正しくフォーマットされていないと思いますが、あなたの例で他に何が間違っているかは不明です。

これは古い投稿ですが、問題を書き留めておきたいと思います。

于 2012-04-12T19:26:09.447 に答える