Indicar um formato de DateTime personalizado ao serializar com Json.Net

Estou a desenvolver uma API para expor alguns dados usando ASP.NET API Web.

numa das API, o cliente quer que exponhamos a data no formato yyyy-MM-dd. Eu não quero mudar as configurações globais (por exemplo GlobalConfiguration.Configuration.Formatters.JsonFormatter) para isso, uma vez que é muito específico para este cliente. E desenvolvo isso numa solução para múltiplos clientes.

uma das soluções que eu poderia pensar é criar um costume {[[3]} e, em seguida, colocar isso na propriedade que eu preciso para fazer o costume formatação

por exemplo

class ReturnObjectA 
{
    [JsonConverter(typeof(CustomDateTimeConverter))]
    public DateTime ReturnDate { get;set;}
}
Só queria saber se há outra maneira fácil de fazer isso.

Author: Vadim Ovchinnikov, 2013-09-05

5 answers

Estás no caminho certo. Uma vez que você disse que não pode modificar as configurações globais, então a próxima melhor coisa é aplicar o atributo JsonConverter de acordo com as necessidades, como você sugeriu. Acontece que ... Json.Net já tem um embutido IsoDateTimeConverter Isso permite-lhe especificar o formato da data. Infelizmente, você não pode definir o formato através do atributo JsonConverter, uma vez que o único argumento do atributo é um tipo. No entanto, existe uma solução simples: subclasse a IsoDateTimeConverter, em seguida, especifique o formato de data em o construtor da subclasse. Aplique o atributo JsonConverter quando necessário, especificando o seu conversor personalizado, e você está pronto para ir. Aqui está a totalidade do código necessário:
class CustomDateTimeConverter : IsoDateTimeConverter
{
    public CustomDateTimeConverter()
    {
        base.DateTimeFormat = "yyyy-MM-dd";
    }
}
Se não se importa de ter tempo lá também, nem precisa de subclassificar o IsoDateTimeConverter. Seu formato de data padrão é yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK (como visto no código fonte).
 102
Author: Brian Rogers, 2017-10-18 17:07:08

Pode usar esta abordagem:

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

E usa-o desta forma:

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

O texto DateTimeFormat usa a sintaxe de texto do formato. net descrita aqui: https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings

 36
Author: Keith Hill, 2017-11-22 02:29:02

Também pode ser feito com uma instância temp IsoDateTimeConverter, sem alterar as configurações de formatação global:

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

Isto usa a sobrecarga que leva um argumento params JsonConverter[].

 34
Author: Saeb Amini, 2017-02-09 23:12:18

Também está disponível usando uma das sobrecarregações da configuração do serializador:

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

Ou

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

Também estão disponíveis sobrecargas para um tipo.

 10
Author: Matt, 2016-04-29 16:25:27

Compilar a classe auxiliar e aplicá-la ao seu atributo de propriedade

Classe auxiliar:

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

O seu código usa assim:

[JsonConverter(typeof(ESDateTimeConverter))]
public DateTime timestamp { get; set; }
 2
Author: Xin, 2018-05-21 06:21:01