如何自定义序列化属性?

时间:2014-04-24 07:27:06

标签: c# .net json serialization

我正在将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);

我该怎么做?

2 个答案:

答案 0 :(得分:1)

除了使用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; }
}

答案 1 :(得分:0)

您始终可以使用自定义代码定义自己的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,并且有一个将MyDateFormatEnum与对象一起使用的Serialize方法,它会在调用Base.Serialise(obj)之前在调用时设置currentFormat属性。可以在应用程序启动时初始化Dictionary。