2013-03-29 2 views
0

Как принять десериализацию JavaScript и изменить имя обрабатываемого объекта?Переименовать свойство из десериализованного Javascript

Например:

class MyClass 
{ 
public string CreateDate {get;set;} 
} 

public class DeserializeMyClass 
{ 
//How do I take "create_date" and convert it to CreateDate? Is there an attribute I 
//can use? 
var json = @"{""create_date"":""04/12/2013""}"; 
var ds = new JavaScriptSerializer(); 

ds.Deserialize<MyClass>(json); 

} 

Заранее спасибо!

+0

Кроме того, вы, вероятно, не хотите проходить такие даты. У вас будут проблемы с локализацией с различными форматами дат. Используйте инвариантный формат, например, ISO8601 'DateTime.ToString (« o »)' и пару с [Moment.js] (http://momentjs.com/) в javascript. –

+0

Уверенная вещь - мне просто нужен быстрый пример, чтобы бросить. – elucid8

ответ

3

Похоже, вы не можете сделать это легко для JavaScriptSerializer, но вы можете сделать это в Json.Net или с помощью DataContractSerializer (часть .Net framework).

Для Json.Net вы можете поместить атрибут JsonProperty, который задает имя.

class MyClass 
{ 
    [JsonProperty(Name="create_date")] 
    public string CreateDate {get;set;} 
} 

И DataContractSerializer использовать DataMember атрибут

+0

Обнаружено ли это в сборке Microsoft? – elucid8

+0

@ elucid8 http://json.codeplex.com/ –

0

Там нет стандартной поддержки для переименования свойств в JavaScriptSerializer однако вы вполне можете легко добавить свои собственные:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Web.Script.Serialization; 
using System.Reflection; 

public class JsonConverter : JavaScriptConverter 
{ 
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) 
    { 
     List<MemberInfo> members = new List<MemberInfo>(); 
     members.AddRange(type.GetFields()); 
     members.AddRange(type.GetProperties().Where(p => p.CanRead && p.CanWrite && p.GetIndexParameters().Length == 0)); 

     object obj = Activator.CreateInstance(type); 

     foreach (MemberInfo member in members) 
     { 
      JsonPropertyAttribute jsonProperty = (JsonPropertyAttribute)Attribute.GetCustomAttribute(member, typeof(JsonPropertyAttribute)); 

      if (jsonProperty != null && dictionary.ContainsKey(jsonProperty.Name)) 
      { 
       SetMemberValue(serializer, member, obj, dictionary[jsonProperty.Name]); 
      } 
      else if (dictionary.ContainsKey(member.Name)) 
      { 
       SetMemberValue(serializer, member, obj, dictionary[member.Name]); 
      } 
      else 
      { 
       KeyValuePair<string, object> kvp = dictionary.FirstOrDefault(x => string.Equals(x.Key, member.Name, StringComparison.InvariantCultureIgnoreCase)); 

       if (!kvp.Equals(default(KeyValuePair<string, object>))) 
       { 
        SetMemberValue(serializer, member, obj, kvp.Value); 
       } 
      } 
     } 

     return obj; 
    } 


    private void SetMemberValue(JavaScriptSerializer serializer, MemberInfo member, object obj, object value) 
    { 
     if (member is PropertyInfo) 
     { 
      PropertyInfo property = (PropertyInfo)member;     
      property.SetValue(obj, serializer.ConvertToType(value, property.PropertyType), null); 
     } 
     else if (member is FieldInfo) 
     { 
      FieldInfo field = (FieldInfo)member; 
      field.SetValue(obj, serializer.ConvertToType(value, field.FieldType)); 
     } 
    } 


    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) 
    { 
     Type type = obj.GetType(); 
     List<MemberInfo> members = new List<MemberInfo>(); 
     members.AddRange(type.GetFields()); 
     members.AddRange(type.GetProperties().Where(p => p.CanRead && p.CanWrite && p.GetIndexParameters().Length == 0)); 

     Dictionary<string, object> values = new Dictionary<string, object>(); 

     foreach (MemberInfo member in members) 
     { 
      JsonPropertyAttribute jsonProperty = (JsonPropertyAttribute)Attribute.GetCustomAttribute(member, typeof(JsonPropertyAttribute)); 

      if (jsonProperty != null) 
      { 
       values[jsonProperty.Name] = GetMemberValue(member, obj); 
      } 
      else 
      { 
       values[member.Name] = GetMemberValue(member, obj); 
      } 
     } 

     return values; 
    } 

    private object GetMemberValue(MemberInfo member, object obj) 
    { 
     if (member is PropertyInfo) 
     { 
      PropertyInfo property = (PropertyInfo)member; 
      return property.GetValue(obj, null); 
     } 
     else if (member is FieldInfo) 
     { 
      FieldInfo field = (FieldInfo)member; 
      return field.GetValue(obj); 
     } 

     return null; 
    } 


    public override IEnumerable<Type> SupportedTypes 
    { 
     get 
     { 
      return new[] { typeof(MyClass) }; 
     } 
    } 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] 
public class JsonPropertyAttribute : Attribute 
{ 
    public JsonPropertyAttribute(string name) 
    { 
     Name = name; 
    } 

    public string Name 
    { 
     get; 
     set; 
    } 
} 

MyClass класс становится:

class MyClass 
{ 
    [JsonProperty("create_date")] 
    public string CreateDate {get;set;} 
} 

Я понимаю, что это может быть немного поздно, но подумал, что другие люди, желающие использовать JavaScriptSerializer, а не Json.Net или «DataContractJsonSerializer», могут это оценить.

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