5

Bitbucket REST API からの応答として、次の JSON オブジェクト (簡略化されたバージョン) を取得しています。

{
    "repositories": [
        {
            "scm": "hg",
            "has_wiki": false,            
            "language": "c#",
            "slug": "Repo1"
        },
        {
            "scm": "hg",
            "has_wiki": false,            
            "language": "java",
            "slug": "Repo2"
        },
        {
            "scm": "hg",
            "has_wiki": true,            
            "language": "c#",
            "slug": "Repo3"
        }
    ],
    "user": {
        "username": "someuser",
        "first_name": "Some",
        "last_name": "User",
        "display_name": "Some User",
        "is_team": false,
        "avatar": "https://someuseravatar.com",
        "resource_uri": "/1.0/users/someuser"
    }
}

この JSON オブジェクトのうち、逆シリアル化する必要があるのはuser一部だけです。その目的のために、次のクラスを作成しました。

[DataContract(Name="user")]
public class BitbucketUser
{
    [DataMember(Name = "username")]
    public string Username { get; set; }

    [DataMember(Name = "first_name")]
    public string FirstName { get; set; }

    [DataMember(Name = "last_name")]
    public string LastName { get; set; }

    [DataMember(Name = "display_name")]
    public string DisplayName { get; set; }

    [DataMember(Name = "is_team")]
    public bool IsTeam { get; set; }

    [DataMember(Name = "avatar")]
    public string Avatar { get; set; }

    [DataMember(Name = "resource_uri")]
    public string ResourceUri { get; set; }
}

そして、json を逆シリアル化するヘルパー メソッド:

public static T Deserialize<T>(string json)
{
    DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T));
    using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(json)))
    {
        T result = (T)deserializer.ReadObject(stream);
        return result;
    }
}

Userしたがって、このコードを使用して逆シリアル化されたオブジェクトを取得しようとすると:

User user = JsonHelper.Deserialize<User>(jsonResponse);

次にuser、すべてのプロパティを含むオブジェクトを作成していますnull。クラスヘッダーで使用する適切な属性を見つけようとしましたが、結果は同じです。また、余分なライブラリ参照を避けるためだけに Json.NET ライブラリを使用していません。また、そのユーザー オブジェクトをUserタイプのプロパティとして保持し、リポジトリ オブジェクトを Repositories[] タイプの配列として保持するラッパー クラスを作成していません。この問題を解決して、null フィールドを持たない逆シリアル化されたユーザー オブジェクトを取得する方法はありますか?

4

2 に答える 2

4

User逆シリアル化している JSON オブジェクトにはプロパティがないため、コードは機能しません。デシリアライザーは確かに、現在のオブジェクトの子を調べて、何かが一致するかどうかを確認しようとしません。

すべきことは、応答オブジェクト全体を表す型を作成することです。その部分に興味がない場合は、repositories省略してください。

次のコードは私にとってはうまくいきます:

[DataContract]
public class BitbucketResponse
{
    [DataMember(Name="user")]
    public BitbucketUser User { get; set; }
}

[DataContract]
public class BitbucketUser
{
    [DataMember(Name = "username")]
    public string Username { get; set; }

    // etc.
}

…

var serializer = new DataContractJsonSerializer(typeof(BitbucketResponse));
using (var stream = …)
{
    var response = (BitbucketResponse)serializer.ReadObject(stream);
    var user = response.User;
}
于 2013-11-18T17:06:34.967 に答える
0

オブジェクトをjsonからyourClassCustomObjectに逆シリアル化するのに役立つコードを書いています。

private async Task<List<BitbucketUser>> MyDeserializerFunAsync()
{
    List<BitbucketUser> book = new List<BitbucketUser>();
    try
    {
       //I am taking my url from appsettings. myKey is my appsetting key. You can write direct your url.
       string url = (string)appSettings["mykey"];
       var request = HttpWebRequest.Create(url) as HttpWebRequest;
       request.Accept = "application/json;odata=verbose";
       var factory = new TaskFactory();
       var task = factory.FromAsync<WebResponse>(request.BeginGetResponse,request.EndGetResponse, null);
       var response = await task;
       Stream responseStream = response.GetResponseStream();
       string data;
       using (var reader = new System.IO.StreamReader(responseStream))
       {
           data = reader.ReadToEnd();
       }
       responseStream.Close();
       DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(List<BitbucketUser>));
       MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(data));
       book = (List<BitbucketUser>)json.ReadObject(ms);
       return book;
   }
} 

上記のコードは私の wp8 アプリケーションで動作しており、試してみるとより高速であり、役に立ちます。非同期操作を実行していますが、BitbucketUser の戻り値の型を使用して簡単なメソッドを作成できます。

于 2013-11-18T05:59:34.407 に答える