从反序列化Javascript中重命名属性

Rename Property from Deserialized Javascript

本文关键字:重命名 属性 Javascript 反序列化      更新时间:2023-09-26

如何反序列化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);
}

提前感谢!

看起来你不能为JavaScriptSerializer轻松做到这一点,但你可以在Json中做到这一点。Net或使用DataContractSerializer (.Net框架的一部分)。

为Json。Net中,你可以把JsonProperty属性指定一个名称。

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

对于DataContractSerializer使用DataMember属性

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 '的人可能会欣赏它。