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

Sta*_*ish 116 c# datetime json.net asp.net-web-api

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

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

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

例如

class ReturnObjectA 
{
    [JsonConverter(typeof(CustomDateTimeConverter))]
    public DateTime ReturnDate { get;set;}
}
Run Code Online (Sandbox Code Playgroud)

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

Bri*_*ers 138

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

class CustomDateTimeConverter : IsoDateTimeConverter
{
    public CustomDateTimeConverter()
    {
        base.DateTimeFormat = "yyyy-MM-dd";
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你不介意在那里也有时间,你甚至不需要继承IsoDateTimeConverter.它的默认日期格式是yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK(如源代码所示).

  • @Koen Zomers - 您从我的日期格式中删除的单引号在技术上是正确的,尽管它们在这里不是绝对必要的。请参阅 [自定义日期和时间格式字符串的文档](http://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx) 中的 _Literal String Delimiters_。但是,我引用的作为`IsonDateTimeConverter` 的默认格式的格式是直接取自 [Json.Net 源代码](http://json.codeplex.com/SourceControl/latest#trunk/Src/Newtonsoft.Json/转换器/IsoDateTimeConverter.cs); 因此,我将恢复您对此的编辑。 (2认同)

小智 72

你可以使用这种方法:

public class DateFormatConverter : IsoDateTimeConverter
{
    public DateFormatConverter(string format)
    {
        DateTimeFormat = format;
    }
}
Run Code Online (Sandbox Code Playgroud)

并以这种方式使用它:

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

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

  • @TamCoton 看到此错误的原因之一可能是您在文件中引用“System.Text.Json`而不是“Newtonsoft.Json”。至少在我的情况下这是问题。 (6认同)
  • 这对我不起作用 - 我得到''JsonConverterAttribute'不包含带2个参数的构造函数 (4认同)
  • 这是最灵活的解决方案。如果您收到以下错误:`'JsonConverterAttribute' 不包含带有 2 个参数的构造函数`,则表示您的 json.net 版本太旧。您需要更新到最新的 json.net 版本。 (3认同)

Sae*_*ini 45

它也可以使用临时IsoDateTimeConverter实例来完成,而无需更改全局格式设置:

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

这使用带JsonConvert.SerializeObject参数的重载.

  • 比接受的答案简单得多 (5认同)
  • 如果您在许多地方序列化相同的类对象,那么接受的答案比这更好 (4认同)

Mat*_*att 13

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

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

要么

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

也可以使用类型超载.

  • 仅供参考,我认为您的意思是yyyy-MM-ddTHH:mm:ssZ .. 24小时制。 (2认同)

Ran*_*nga 10

带有下面的转换器

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

        public CustomDateTimeConverter(string format)
        {
            DateTimeFormat = format;
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

class ReturnObjectA 
{
    [JsonConverter(typeof(CustomDateTimeConverter))]
    public DateTime ReturnDate { get;set;}
}
Run Code Online (Sandbox Code Playgroud)

或属性的任何指定格式

class ReturnObjectB 
{
    [JsonConverter(typeof(CustomDateTimeConverter), "dd MMM yy")]
    public DateTime ReturnDate { get;set;}
}
Run Code Online (Sandbox Code Playgroud)


Ant*_*uez 6

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

class JSonModel {
    ...

    [JsonIgnore]
    public DateTime MyDate { get; set; }

    [JsonProperty("date")]
    public string CustomDate {
        get { return MyDate.ToString("ddMMyyyy"); }
        // set { MyDate = DateTime.Parse(value); }
        set { MyDate = DateTime.ParseExact(value, "ddMMyyyy", null); }
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

这样您就不必创建额外的类。此外,它还允许您创建不同的数据格式。例如,您可以使用相同的日期时间轻松地为小时创建另一个属性。


Xin*_*Xin 5

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

助手班:

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

您的代码使用如下:

[JsonConverter(typeof(ESDateTimeConverter))]
public DateTime timestamp { get; set; }
Run Code Online (Sandbox Code Playgroud)

  • 您为什么还要重申其他几个人已经说过的话? (5认同)