25

新しいStackOverflow APIで少し遊んでいます。残念ながら、私の JSON は少し弱いので、助けが必要です。

ユーザーのこの JSON を逆シリアル化しようとしています。

  {"user":{
    "user_id": 1,
    "user_type": "moderator",
    "creation_date": 1217514151,
    "display_name": "Jeff Atwood",
    ...
    "accept_rate": 100
  }}

属性で装飾したオブジェクトにJsonProperty:

[JsonObject(MemberSerialization.OptIn)]
public class User
{
    [JsonProperty("user_id", Required = Required.Always)]        
    public virtual long UserId { get; set; }

    [JsonProperty("display_name", Required = Required.Always)]
    public virtual string Name { get; set; }

    ...
}

次の例外が発生します。

Newtonsoft.Json.JsonSerializationException: 必要なプロパティ 'user_id' が JSON に見つかりません。

これは、JSON オブジェクトが配列だからですか? もしそうなら、どうすれば1つの User オブジェクトに逆シリアル化できますか?

前もって感謝します!

4

3 に答える 3

36

ラッパー クラスを作成したくない場合は、次の方法で User にアクセスすることもできます。

String jsonString = "{\"user\":{\"user_id\": 1, \"user_type\": \"moderat...";
JToken root = JObject.Parse(jsonString);
JToken user = root["user"];
User deserializedUser = JsonConvert.DeserializeObject<User>(user.ToString());

詳細については、Json.NET ドキュメントのこのページを参照してください。

于 2010-03-31T19:31:40.483 に答える
27

Alexandre Jasmin が質問のコメントで述べたように、結果の JSON には、User逆シリアル化しようとしている実際のオブジェクトのラッパーがあります。

回避策は、次のラッパー クラスを使用することです。

public class UserResults
{
    public User user { get; set; }
}

次に、逆シリアル化が機能します。

using (var sr = new StringReader(json))
using (var jr = new JsonTextReader(sr))
{
    var js = new JsonSerializer();
    var u = js.Deserialize<UserResults>(jr);
    Console.WriteLine(u.user.display_name);
}

このラッパーには、応答タイムスタンプなどの将来のメタデータ プロパティがあるため、それを使用することは悪い考えではありません。

于 2010-03-31T19:28:16.230 に答える
5

@Alexandre Jasmin のanswerJsonConvertと同様に、高レベルのonを使用する代わりに、中間の JsonSerializer を使用して変換できます.ToString()。それがより効率的かどうかはわかりません...

参考文献:

例:

var root = JObject.Parse(jsonString);
var serializer = new JsonSerializer();
var expectedUserObject = serializer.Deserialize<User>(root["user"].CreateReader());
于 2013-01-25T17:47:45.637 に答える