使用Json.Net进行序列化时指定自定义DateTime格式

时间:2013-09-05 11:52:58

标签: c# datetime asp.net-web-api json.net

我正在开发一个API来使用ASP.NET Web API公开一些数据。

在其中一个API中,客户希望我们以yyyy-MM-dd格式公开日期。我不想更改全局设置(例如GlobalConfiguration.Configuration.Formatters.JsonFormatter),因为它非常特定于此客户端。我在多个客户的解决方案中进行开发。

我能想到的解决方案之一是创建自定义JsonConverter,然后将其放入我需要执行自定义格式设置的属性

e.g。

class ReturnObjectA 
{
    [JsonConverter(typeof(CustomDateTimeConverter))]
    public DateTime ReturnDate { get;set;}
}

只是想知道是否还有其他一些简单的方法。

9 个答案:

答案 0 :(得分:125)

你走在正确的轨道上。由于您说您无法修改全局设置,因此下一个最好的方法是根据您的建议根据需要应用JsonConverter属性。事实证明,Json.Net已经有一个内置的IsoDateTimeConverter,可以让你指定日期格式。遗憾的是,您无法通过JsonConverter属性设置格式,因为属性的唯一参数是类型。但是,有一个简单的解决方案:子类IsoDateTimeConverter,然后在子类的构造函数中指定日期格式。在需要的地方应用JsonConverter属性,指定自定义转换器,然后就可以开始了。以下是所需的全部代码:

class CustomDateTimeConverter : IsoDateTimeConverter
{
    public CustomDateTimeConverter()
    {
        base.DateTimeFormat = "yyyy-MM-dd";
    }
}

如果你不介意在那里也有时间,你甚至不需要继承IsoDateTimeConverter。其默认日期格式为yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK(如source code中所示)。

答案 1 :(得分:59)

你可以使用这种方法:

public class DateFormatConverter : IsoDateTimeConverter
{
    public DateFormatConverter(string format)
    {
        DateTimeFormat = format;
    }
}

并以这种方式使用它:

class ReturnObjectA 
{
    [JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd")]
    public DateTime ReturnDate { get;set;}
}

DateTimeFormat字符串使用此处描述的.NET格式字符串语法:https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings

答案 2 :(得分:39)

也可以使用临时IsoDateTimeConverter实例,而不更改全局格式设置:

string json = JsonConvert.SerializeObject(yourObject,
    new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });

这使用带有params JsonConverter[]参数的重载。

答案 3 :(得分:12)

也可以使用其中一个串行器设置重载:

var json = JsonConvert.SerializeObject(someObject, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });

或者

var json = JsonConvert.SerializeObject(someObject, Formatting.Indented, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });

也可以使用类型超载。

答案 4 :(得分:4)

构建帮助程序类并将其应用于属性属性

助手类:

public class ESDateTimeConverter : IsoDateTimeConverter
{
    public ESDateTimeConverter()
    {
        base.DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
    }
}

您的代码使用如下:

[JsonConverter(typeof(ESDateTimeConverter))]
public DateTime timestamp { get; set; }

答案 5 :(得分:2)

public static JsonSerializerSettings JsonSerializer { get; set; } = new JsonSerializerSettings()
        {
            DateFormatString= "yyyy-MM-dd HH:mm:ss",
            NullValueHandling = NullValueHandling.Ignore,
            ContractResolver = new LowercaseContractResolver()
        };

你好

我在需要设置 JsonSerializerSettings 时使用此属性

答案 6 :(得分:1)

我一直在使用另一种解决方案。只需创建一个字符串属性并将其用于json。该属性的返回日期格式正确。

class JSonModel {
    ...

    private DateTime myDate;
    [JsonProperty("date")]
    public string CustomDate {
        get { return myDate.ToString("DDMMYY"); }
        set { myDate = DateTime.Parse(value); }
    }

    ...
}

这样,您不必创建额外的类。此外,它还允许您创建不同的数据格式。例如,您可以使用相同的DateTime轻松为Hour创建另一个Property。

答案 7 :(得分:0)

有时装饰json convert属性将无法正常工作,它会通过例外方式指出“ 2010-10-01”为有效日期 。为了避免这种类型,我删除了该属性上的json convert属性,并在如下所述的deserilizedObject方法中提到了。

var addresss = JsonConvert.DeserializeObject<AddressHistory>(address, new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" });

答案 8 :(得分:0)

具有以下转换器

public class CustomDateTimeConverter : IsoDateTimeConverter
    {
        public CustomDateTimeConverter()
        {
            DateTimeFormat = "yyyy-MM-dd";
        }

        public CustomDateTimeConverter(string format)
        {
            DateTimeFormat = format;
        }
    }

可以使用默认的自定义格式使用

class ReturnObjectA 
{
    [JsonConverter(typeof(DateFormatConverter))]
    public DateTime ReturnDate { get;set;}
}

或属性的任何指定格式

class ReturnObjectB 
{
    [JsonConverter(typeof(DateFormatConverter), "dd MMM yy")]
    public DateTime ReturnDate { get;set;}
}