2014-03-25 81 views
1

我正在使用WebAPI,它依賴於JSON格式的JSON .NET。 C#的身邊,我有一個DTO,看起來像這樣:JSON .NET截取反序列化屬性名稱

public class DTO1 : IManifestContainer 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; }   
    public HashSet<string> Manifest { get; private set; } 
} 
public interface IManifestContainer 
{ 
    HashSet<string> Manifest { get; } 
} 

的IManifestContainer界面的想法是跟蹤客戶端實際上是發送到服務器的JSON對象的屬性。例如,如果客戶端發送此JSON:

{"FirstName":"Jojo"} 

清單哈希集僅包含「FirstName」。 如果客戶端發送:

{"FirstName":"Jojo", "LastName":"Jones"} 

清單中的HashSet將包含「名字」和「姓氏」。

我試圖實現JsonConverter這樣的:

public class ManifestJsonConverter : JsonConverter 
{ 
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
{ 
    if (reader.TokenType == JsonToken.Null) 
    { 
     return null; 
    } 

    JObject jObject = JObject.Load(reader); 

    // Convert the JObject to a C# object?? 
    // Passing the serializer will call this method again 
    object retVal = jObject.ToObject(objectType, serializer); 

    IManifestContainer manifestContainer = (IManifestContainer) retVal; 

    foreach (var jProperty in jObject.Properties()) 
    { 
     manifestContainer.Manifest.Add(jProperty.Name); 
    } 
    return retVal; 
} 

public override bool CanConvert(Type objectType) 
{ 
    return typeof (IManifestContainer).IsAssignableFrom(objectType); 
} 
} 

我需要加載JObject獲得來自客戶端的所有屬性,但我不知道如何創建的objectType的「實例「(C#DTO)來自JObject。

回答

0

您可以嘗試使用JObject.ToObject的過載,該過載不包含JsonSerializer。在這種情況下,ToObject方法將使用不知道轉換器的新序列化器實例,只要您沒有使用[JsonConverter]屬性修飾DTO類,就應該允許它運行。

object retVal = jObject.ToObject(objectType); 

如果這不起作用,您的其他選項是手動創建DTO實例並通過反射來填充它們的屬性。

+0

我需要保持相同的序列化程序,因爲它包含其他設置,我必須保留反序列化整個圖形。 – oscarmorasu

1

看完之後this other post我想出了這個實現。這涵蓋了所有情況。

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
     { 
      return null; 
     } 

     JObject jObject = JObject.Load(reader); 

     JArray manifestArray = new JArray(); 

     foreach (var jProperty in jObject.Properties()) 
     { 
      manifestArray.Add(jProperty.Name); 
     } 

     jObject["Manifest"] = manifestArray; 

     var retVal = Activator.CreateInstance(objectType); 

     serializer.Populate(jObject.CreateReader(), retVal); 

     return retVal; 
    } 
相關問題