4

В ответ от API Bitbucket REST я получаю следующий объект JSON (упрощенный вариант):Частичное десериализации объекта JSON с помощью DataContractJsonSerializer

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

And вспомогательного метод для десериализации 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 [] , Есть ли решение этой проблемы для получения десериализованного пользовательского объекта без нулевых полей?

+0

«Я не использую библиотеку Json.NET только чтобы избежать дополнительных ссылок библиотека» Это библиотека ссылки действительно что-то избежать? Даже Microsoft теперь распространяет некоторые свои библиотеки через NuGet. – svick

+0

http://www.newtonsoft.com/json/help/html/SerializingJSONFragments.htm вот как это сделать с помощью newtonsoft.json (получил этот вопрос как первый в google, поэтому он может быть полезен другим) – pajics

ответ

4

Ваш код не работает, потому что объект JSON, который вы десериализуете, не имеет никаких свойств User. Конечно, десериализатор не будет искать детей текущего объекта, чтобы убедиться, что что-то соответствует.

Что вы должны сделать, так это создать тип, представляющий весь объект ответа. Если вас не интересует часть 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; 
} 
+0

Это единственный способ достичь цели без сторонних библиотек. – Arterius

+0

@Arterius Я считаю, что, вероятно, это возможно с использованием JavaScriptSerializer с настраиваемыми типами, которые не потребуют сторонних библиотек, но это должно делать трюк в любом случае –

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.

+1

Но JSON не массив пользователей, поэтому я думаю, что этот код не будет работать. – svick

+0

, но ваш json выполняет стандартный формат json, не так ли? если да, то это будет работать. Я думаю, вы должны попробовать один раз. Ваша попытка поможет исправить себя, если этот код не будет работать в вашем случае. –

+1

Это не «мой» JSON, я не тот, кто задал вопрос. Но, как я уже сказал, JSON, размещенный в вопросе, не является множеством пользователей, поэтому я не вижу, как этот код может работать. – svick

Смежные вопросы