C# 如何自定义序列化属性?

C# 如何自定义序列化属性?,c#,.net,json,serialization,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 JavaScrip

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

如何实现这一点?

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

编辑

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

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; }
    }
}
当然,代码仍然需要处理默认值和错误处理,但它应该说明我的想法。您还可以将YourOrg_JavaScriptSerializer类中的格式设置为IDictionary静态格式,并使用Serialize方法将MyDateFormatEnum与对象一起接受,它将在调用Base.Serialise(obj)之前在调用时设置currentFormat属性。字典可以在应用程序启动时初始化。

除了使用外,还可以使用以下技巧:

[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; }
}

如何进行序列化?请查看更新的问题!似乎我不能使用未序列化的
?它不起作用还是(编译)错误?我还没有测试过这段代码——这或多或少是我想向您展示的模式。JTMon的链接是解决这个问题的一种更通用的方法,在本例中,我更喜欢…编译错误。好像那个阶级不存在?!?!它应该是:嘿,如果你喜欢@chrfin解决方案,那么在不使用NotSerialized的情况下使用它会很好。我需要自定义字段“动态”的自定义类型。您的解决方案适用于一个场景!什么id我想要两种不同类型的DateTime?您可以使格式字符串成为在创建时注入类的属性,并具有所需的格式。您能为我的案例编写一个完整的示例吗?
var mySerializer = new YourOrg_JavaScriptSerializer("FormatThatINeed");
mySerializer.Serialize(obj);
[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; }
}