2013-09-05 14 views
58

Ich entwickle eine API, um einige Daten mithilfe der ASP.NET-Web-API verfügbar zu machen.Angeben eines benutzerdefinierten DateTime-Formats beim Serialisieren mit Json.Net

In einer der API möchte der Client uns das Datum im Format JJJJ-MM-TT anzeigen. Ich möchte die globalen Einstellungen (z. B. GlobalConfiguration.Configuration.Formatters.JsonFormatter) nicht ändern, da sie für diesen Client sehr spezifisch sind. Und ich entwickle das in einer Lösung für mehrere Kunden.

Einer der Lösung, die ich denken konnte, ist ein benutzerdefinierter Json-Konverter zu erstellen und das dann auf die Eigenschaft hat ich die benutzerdefinierte Formatierung

zum Beispiel tun müssen

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

Ich frage mich nur, ob es eine andere einfache Möglichkeit gibt, das zu tun.

+8

Für das, was es ist wert, APIs sind für Computer Lesbarkeit, nicht Benutzer Lesbarkeit, so ist es besser, zu einem einzigen angegebenen Datumsformat zu bleiben, wie [ISO 8601] (http://xkcd.com/1179/). Wenn der Client dem Benutzer das API-Ergebnis direkt anzeigt oder seinen eigenen Parsing-Code für die API schreibt, tun sie es falsch. Das Formatieren eines Datums für die Anzeige sollte auf der obersten UI-Ebene verbleiben. – MCattle

Antwort

91

Sie sind auf dem richtigen Weg. Da Sie gesagt haben, dass Sie die globalen Einstellungen nicht ändern können, ist die nächstbeste Lösung, das Attribut JsonConverter je nach Bedarf anzuwenden, wie Sie es vorgeschlagen haben. Es stellt sich heraus, Json.Net hat bereits eine eingebaute IsoDateTimeConverter, mit der Sie das Datumsformat angeben können. Leider können Sie das Format nicht über das Attribut JsonConverter festlegen, da das einzige Argument des Attributs ein Typ ist. Es gibt jedoch eine einfache Lösung: Unterklasse IsoDateTimeConverter, dann geben Sie das Datumsformat im Konstruktor der Unterklasse an. Wenden Sie das Attribut JsonConverter dort an, wo Sie es benötigen, geben Sie Ihren benutzerdefinierten Konverter an, und schon kann es losgehen. Hier ist die Gesamtheit des Codes benötigt:

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

Wenn Sie nichts dagegen haben dort auch die Zeit haben, brauchen Sie nicht einmal die IsoDateTimeConverter Unterklasse. Das Standarddatumsformat ist yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK (wie in der source code zu sehen ist).

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

Dies verwendet die Überlastung, die ein params JsonConverter[] Argument:

+0

@Koen Zomers - Die einfachen Zitate, die Sie technisch aus meinen Datumsformaten entfernt haben, sind korrekt, obwohl sie hier nicht unbedingt notwendig sind. Weitere Informationen finden Sie unter _Literal String Delimiters_ in der Dokumentation für benutzerdefinierte Formatstrings für Datum und Uhrzeit (http://msdn.microsoft.com/en-us/library/8kb3ddd4 (v = vs.110) .aspx). Das Format, das ich als Standardformat für den 'IsonDateTimeConverter' angegeben habe, wurde jedoch direkt vom [Json.Net-Quellcode] übernommen (http://json.codeplex.com/SourceControl/latest#trunk/Src/Newtonsoft.Json/ Konverter/IsoDateTimeConverter.cs); Daher setze ich deine Bearbeitung darauf zurück. –

+0

es hat hier mit den Zitaten nicht funktioniert und es ist ohne sie gegangen, aber wenn du es sagst, habe ich wahrscheinlich etwas falsch gemacht. Entschuldigung für die Bearbeitung. –

+0

Vielen Dank :) mit Leichtigkeit gearbeitet! – Erik

25

Es kann auch mit einer temporären IsoDateTimeConverter Instanz, ohne Änderung globale Formatierungseinstellungen vorgenommen werden.

+4

Viel einfacher als die angenommene Antwort – FastTrack

+0

Noch zeigt es eine T, wo das Leerzeichen ist :( – DARKGuy

+1

Wenn Sie self-class Objekt an vielen Orten serialisieren, dann ist die akzeptierte Antwort besser als diese –

8

Auch eine der Serializer Einstellungen Überlastungen mit:

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

Oder

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

Überlastungen eine Art nehmen sind ebenfalls erhältlich.

+0

perfekt und toller Trick – user6628729

+0

fühlen Sie sich frei zu geben mir ein upvote dann!;) – Matt

+0

FYI ich denke du meinst "JJJJ-MM-TTTHH: mm: ssZ" .. 24 Stunden Uhr auf die Stunden. – Neek

23

könnten Sie diesen Ansatz verwenden:

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

Und es auf diese Weise verwenden:

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

Das Datetimeformat Zeichenfolge verwendet die .NET Format-String-Syntax hier beschrieben: https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings

+0

base.DateTimeFormat = Format; – SoliQuiD

+0

Dies ist die beste Antwort, da es leicht zu verstehen und sehr erweiterbar ist. –

+1

Dies funktioniert nicht für mich - ich bekomme "JsonConverterAttribute" enthält keinen Konstruktor, der 2 Argumente akzeptiert –

Verwandte Themen