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

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

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

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

例如:。

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

只是想知道是否有其他简单的方法可以做到这一点。

222724 次浏览

你的方向是对的。既然您说过不能修改全局设置,那么接下来最好的事情就是根据需要应用 JsonConverter属性,就像您建议的那样。原来杰森。Net 已经有一个内置的 IsoDateTimeConverter,允许您指定日期格式。遗憾的是,您不能通过 JsonConverter属性设置格式,因为该属性的唯一参数是一个类型。但是,有一个简单的解决方案: 将 IsoDateTimeConverter作为子类,然后在子类的构造函数中指定日期格式。在需要的地方应用 JsonConverter属性,指定自定义转换器,就可以开始了。以下是所需代码的全部内容:

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

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

它也可以通过 IsoDateTimeConverter实例完成,而无需更改全局格式设置:

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

这将使用接受 params JsonConverter[]参数的 JsonConvert.SerializeObject重载。

也可以使用序列化程序设置重载之一:

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" });

采用 Type 的重载也是可用的。

你可以使用这种方法:

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://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings

有时候修饰 json 转换属性不起作用,它会通过异常说“ < em > 2010-10-01”有效日期 。为了避免这种类型,我移除了属性上的 json 转换属性,并且在 desilizedObject 方法中提到了,如下所示。

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

我还有一个办法。只需创建一个字符串属性并将其用于 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); }
}


...
}

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

以下转换器

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


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

可以将其与默认自定义格式一起使用

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

或属性的任何指定格式

class ReturnObjectB
{
[JsonConverter(typeof(CustomDateTimeConverter), "dd MMM yy")]
public DateTime ReturnDate { get;set;}
}
public static JsonSerializerSettings JsonSerializer { get; set; } = new JsonSerializerSettings()
{
DateFormatString= "yyyy-MM-dd HH:mm:ss",
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new LowercaseContractResolver()
};

你好,

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