2017-01-31 11 views
2

я создал следующий класс для представления любого ответа сервера для запросов REST API:включают в себя имя класса в формате JSON Generic собственности Сериализации

[DataContract] 
public class ServerResponse<T> 
{ 
    [DataMember(Name = "error")] 
    public string ErrorMessage { get; set; } 

    [DataMember(Name = "data")] 
    public T Data { get; set; } 

    [DataMember(Name = "success")] 
    public bool Success { get; set; } 
} 

При его использовании с помощью простого класса как этого

[DataContract(Name = "category")] 
public class Category 
{ 
    [DataMember(Name = "id")] 
    public int Id { get; set; } 

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

я получаю следующий ответ

{ 
    "error": "", 
    "data": { 
     "id": 3, 
     "name": "Top" 
    }, 
    "success": true 
} 

Я хочу, чтобы включить общий тип C имя лазера в сериализации. желаемый результат:

{ 
    "error": "", 
    "data": { 
     "category": { 
      "id": 3, 
      "name": "Top" 
     } 
    }, 
    "success": true 
} 

Как я могу это сделать? (я видел ответы в подобных сообщениях, но не из них относятся к общей ситуации, как этот)

ответ

0

Я отправляю мой обходной путь, если это поможет никому

Я создал пользовательский JSon конвертер

public class GenericTypeJsonSerializer : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     // Parse data object 
     var dataObject = JToken.FromObject(value); 

     // Extract generic type class serialization name 
     var className = ExtractClassName(value); 

     // Create wrapper object that includes generic class name 
     JObject wrapperObject = new JObject(); 
     wrapperObject.Add(className, dataObject); 

     // write object 
     wrapperObject.WriteTo(writer); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return true; 
    } 

    public string ExtractClassName(object value) 
    { 
     // extract data contract attribute 
     var dataContractAttribute = value.GetType() 
      .GetCustomAttribute(typeof(DataContractAttribute)) as DataContractAttribute; 
     // return name declared in attribute 
     if (dataContractAttribute?.Name != null) 
      return dataContractAttribute.Name; 

     // return default class name 
     return value.GetType().Name; 
    } 
} 

И я украсил общий Data свойство с атрибутом JsonConverter

[JsonConverter(typeof(GenericTypeJsonSerializer))] 
    [DataMember(Name = "data")] 
    public T Data { get; set; } 

c'est tout!