2013-09-05 42 views
58

ile serileştirirken özel bir DateTime biçemi belirtme ASP.NET Web API kullanarak bazı verileri açığa çıkarmak için bir API geliştiriyorum.Json.Net

API'den birinde, istemci tarihi yyyy-MM-dd biçiminde göstermemizi ister. Global ayarları (örneğin, GlobalConfiguration.Configuration.Formatters.JsonFormatter) değiştirmek istemiyorum çünkü bu istemci için çok özel. Ve bunu birden çok müşteri için bir çözümde geliştiriyorum. Aklıma gelen solüsyonun

biri özel bir Json dönüştürücü oluşturmak ve sonra özel biçimlendirme

örneğin yapmanız gereken mülke o koymaktır

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

Bunu yapmanın başka bir kolay yolu olup olmadığını merak ediyorum.

+8

:

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

DateTimeFormat dize Burada anlatılan .NET biçim dizesi sözdizimi kullanır değer, API'lar kullanıcı tarafından okunabilir değil, bilgisayar okunabilirliği içindir, bu yüzden [ISO 8601] gibi bir tek bir tarih formatına bağlı kalmak daha iyidir (http://xkcd.com/1179/). İstemci doğrudan API sonucunu kullanıcıya gösteriyorsa veya API için kendi tarih ayrıştırma kodunu yazıyorsa, yanlış yapıyorlar demektir. Ekran için bir tarih biçimlendirmek, en üstteki UI katmanına bırakılmalıdır. – MCattle

cevap

91

Doğru yoldasın. Global ayarları değiştiremeyeceğinizi söylediğinizden, bir sonraki en iyi şey önerdiğiniz gibi JsonConverter özniteliğini gerektiği gibi uygulamaktır. Bu, Json.Net'in zaten tarih biçimini belirtmenize olanak tanıyan dahili bir IsoDateTimeConverter içeriyor. Ne yazık ki, özniteliğin tek argümanı bir tür olduğu için, biçimi JsonConverter özniteliği aracılığıyla ayarlayamazsınız. Ancak, basit bir çözüm var: IsoDateTimeConverter alt sınıfını seçin, sonra alt sınıfın yapıcısında tarih biçimini belirtin. Gerekirse, özel dönüştürücünüzü belirterek JsonConverter özniteliğini uygulayın ve kullanmaya hazırsınız. İşte gereken kod bütünüdür:

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

orada da içinde vakit geçiriyor sakıncası yoksa, hatta IsoDateTimeConverter alt sınıf gerekmez. Varsayılan tarih biçimi yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK'dir (source code'da görüldüğü gibi).

+0

@Koen Zomers - Tarih biçimlerinden teknik olarak kaldırdığınız tek tırnaklar, burada kesinlikle gerekli olmalarına rağmen doğrudur. [Özel Tarih ve Saat Formatı Dizeleri'nin belgelerinde] _Literal String Delimiters_ bölümüne bakın (http://msdn.microsoft.com/en-us/library/8kb3ddd4 (v = vs.110) .aspx). Ancak, "IsonDateTimeConverter" için varsayılan biçim olarak alıntılanan biçim doğrudan [Json.Net kaynak kodu] 'dan alınmıştır (http://json.codeplex.com/SourceControl/latest#trunk/Src/Newtonsoft.Json/ Dönüştürücüler/IsoDateTimeConverter.cs); bu yüzden bu konudaki düzenlemeni geri alıyorum. –

+0

burada alıntılar ile işe yaramadı ve onlar olmadan yaptı, ama eğer söylerseniz, muhtemelen yanlış bir şey yaptım. Düzenleme için üzgünüm. –

+0

Çok teşekkür ederim :) çok çalıştı! – Erik

25

Ayrıca küresel biçimlendirme ayarlarını değiştirmeden, geçici IsoDateTimeConverter örneği ile yapılabilir:

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

Bu params JsonConverter[] argüman alır aşırı kullanır.

+4

Kabul edilen yanıttan çok daha basit – FastTrack

+0

Yine de uzay karakterinin olduğu bir T gösterir :( – DARKGuy

+1

Aynı sınıf nesnesini birçok yerde serileştiriyorsanız, kabul edilen yanıt bu –

8

da bulunmakta serileştirici ayarları aşırı birini kullanarak: Bir Tür alarak

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

Ya

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

Overloads de mevcuttur.

+0

mükemmel ve harika hile – user6628729

+0

vermekten daha iyidir o zaman bana bir vuruyor!;) – Matt

+0

FYI Sanırım yyyy-MM-ddTHH: mm: ssZ'. Saatlerde 24 saat saat. – Neek

23

Bu yaklaşım kullanabilirsiniz:

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

Ve bu şekilde kullanın: o ne için https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings

+0

base.DateTimeFormat = format; – SoliQuiD

+0

Bu, anlaşılması kolay ve yüksek ölçüde genişletilebilir olduğu için en iyi yanıttır. –

+1

Bu benim için çalışmaz - 'JsonConverterAttribute' 2 argüman alır bir kurucu içermez –