如何自定义序列化属性

本文关键字:属性 序列化 自定义 | 更新日期: 2023-09-27 18:00:02

我正在将json序列化到我的类中:

[Serializable]
public class Feed
{
    public string id { get; set; }
    public string id_str { get; set; }
    public User user  { get; set; }
    public DateTime created_at { get; set; }
}
JavaScriptSerializer jss= new JavaScriptSerializer();
Feed feed = jss.Deserialize<Feed>(json); 

有一个名为created_at的字段,但我不想直接存储它,因为它来自json,而是先处理它,例如:

DateTime.ParseExact(created_at, "ddd MMM dd HH:mm:ss zzzz yyyy", CultureInfo.InvariantCulture);

我该怎么做?

如何自定义序列化属性

除了使用JavsScriptConverters,您还可以使用这样的技巧:

[Serializable]
public class Feed
{
    public string id { get; set; }
    public string id_str { get; set; }
    public User user  { get; set; }
    public string created_at 
    { 
        get { return CreatedAt.ToString(FORMAT); }
        set { CreatedAt = DateTime.ParseExact(value, "ddd MMM dd HH:mm:ss zzzz yyyy", CultureInfo.InvariantCulture); }
    }
    [NotSerialized]
    public DateTime CreatedAt { get; set; }
}

您可以始终使用日期时间序列化反序列化的自定义代码定义自己版本的JavaScriptSerializer,并使用该代码而不是标准代码。看看这里的一个好例子

http://www.codeproject.com/Articles/608464/CustomplusDatesplusJavascriptplusSerializer

编辑

我已经修改了上面链接中的代码。

using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
// Your Organization serializer. Override the key methods for the desired date format.
// This example formats the date as MM/dd/yyyy
public class YourOrg_JavaScriptSerializer : JavaScriptSerializer
{
    public string CurrentFormat { get; set; }
    public YourOrg_JavaScriptSerializer(string format)
        : base()
    {
        this.CurrentFormat = format;
        this.RegisterConverters(new JavaScriptConverter[] { new DateStringJSONConverter() });
    }
}
public class DateStringJSONConverter : JavaScriptConverter
{
    private List<Type> supportedTypes;
    public DateStringJSONConverter()
    {
        supportedTypes = new List<Type>(1);
        supportedTypes.Add(typeof(DateTime));
    }
    public override object Deserialize(IDictionary<string,Object>
    dictionary, Type type, JavaScriptSerializer serializer)
    {
        var dt = DateTime.ParseExact(dictionary
        ["DateString"].ToString(), GetFormatString(serializer), null);
        return dt;
    }
    private string GetFormatString(JavaScriptSerializer serializer)
    {
        var formatString = "MM/dd/yyyy";
        var mySerializer = serializer as YourOrg_JavaScriptSerializer;
        if (mySerializer != null)
        {
            formatString = mySerializer.CurrentFormat;
        }
        return formatString;
    }
    public override IDictionary<string,Object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var dt = Convert.ToDateTime(obj);
        var dicDateTime = new Dictionary<string,Object>(1)
                              {
                                  {"DateString", dt.ToString(GetFormatString(serializer))}
                              };
        return dicDateTime;
    }
    public override IEnumerable<Type> SupportedTypes
    {
        get { return this.supportedTypes; }
    }
}

使用它:

var mySerializer = new YourOrg_JavaScriptSerializer("FormatThatINeed");
mySerializer.Serialize(obj);

当然,代码仍然需要处理默认值和错误处理,但它应该说明我的想法。还可以将YourOrg_JavaScriptSerializer类中的格式设置为IDictionary,并具有一个Serialize方法,该方法将MyDateFormatEnum与对象一起使用,它将在调用Base.Serialize(obj)之前的调用时设置currentFormat属性。Dictionary可以在应用程序启动时初始化。