2013-10-30 26 views
16

Böyle bir POCO vardır:ServiceStack - Tüm seri hale getirilmiş tarihleri ​​belirli bir DateTimeKind kullanmaya zorlamanın bir yolu var mı?

o Entity Framework gelen sulu ediliyor Çoğu zaman
public class BlogEntry 
{ 
    public string Title { get; set; } 
    public DateTime Date { get; set; } 
} 

, ancak ve Varlık Framework dışında delil olarak kullanılabilir.

EF Tarihinden DateTimeKind, Okuduğumdan normal olan Tarihsizdir.

Bu POCO'yu Redis'te (ServiceStack Redis istemcisini kullanarak) önbelleğe aldığımda, bir DateTimeKind of Local ile birlikte gelir.

Bu yüzden döndürülen nesnelerle bir titreme var. İlk geçiş (önbelleğe alınmamış), ofset olmaksızın ISO-8061'e (DateTimeKind.Unspecified) sahiptir. İkinci geçiş (önbelleğe alınmış) bir ofsetle (Redis with DateTimeKind.Local) ISO-8061'dir.

ServiceStack JSON serileştiricisini, tarihleri ​​her zaman bir DateTimeKind olarak yorumlamak için zorlamanın herhangi bir yolu var mı? (Bir "JsConfig.AppendUtcOffset" özelliği olduğunu biliyorum, ancak bu doğru veya yanlış olup olmadığını, değerler benim için hiç değişmez mi?)

Ya da DateTimeKind yerel yapmak için yazılan RedisClient gelen serileştirme işlemi bir yerde?

POCO'larım DateTimeKind'i zorlamak için el ile değiştirebilirim - ve bu işe yarıyor - ama daha az hata eğilimli bir şey olmasını umuyordum.

cevap

16

sen @ mythz cevabı daha yapılandırılabilir bir şey gerekiyorsa, geçersiz kılarak belli DateTimeKind olması tarihsaat seri hale veya deserialization zorlayabilir DateTime ve isteğe bağlı olarak DateTime? serileştirme ve/veya serileştirme yöntemleri.

Kuvvet tüm tefrika tarihsaat DateTime belirtilen bir formatta değilse o zaman serisini kaldırma bu tek öteye adım ve hatayı alabilir UTC

JsConfig<DateTime>.SerializeFn = time => new DateTime(time.Ticks, DateTimeKind.Local).ToString(); 

olarak yorumlanmalıdır. İstemcileri, tüm isteklerde saat dilimini belirtmeye zorlamak istediğimde kullanmaya başladım, ancak zorunlu olarak her zaman Utc olmasını gerektirmiyordu.

JsConfig<DateTime>.DeSerializeFn = time => 
{ 
    if (!IsInCorrectDateFormat(time)) 
    throw new System.Runtime.Serialization.SerializationException(BadDateTime); 

    return ServiceStack.Text.Common.DateTimeSerializer.ParseDateTime(time); 
}; 
+0

'JsConfig .SerializeFn' delegesinin kurulumumda neden çağrılmadığına dair herhangi bir fikir var mı? – ygormutti

+1

Nişanlı DateTime ile seri hale getiriliyor musunuz? –

+0

Ygormutti çözümünü hemen bulamayanlar gibi ... sadece yapmanız gereken tek şey şudur: 'JsConfig .SerializeFn' –

6

DateTimeKind ofseti, Tarih ile birlikte saklanmaz, bu nedenle ServiceStack serileştiricileri, tarihin yerel olduğunu kabul eder, UTC olarak serileştirilir ve Yerel olarak geri seri halinde gönderilir.

Sen DateTimeKind.Unspecified alabilirsiniz ile UTC olarak kabul edilecek:

JsConfig.AssumeUtc = true; 
+0

Önerinizde takılı ve benim için çalışmaya çok yakındı. İlk çağrı örneği: "2013-07-19T12: 49: 52.5570000", ikinci çağrı örneği: "2013-07-19T19: 49: 52.5570000Z". Teknik olarak her ikisi de herhangi bir dil tarafından ayrılabilir olmalı ve ben de aynı şeyi elde ettiğimi varsayalım, ama onları mükemmel bir şekilde eşleştirmek için güçlü bir isteğim var. – ryan1234

+0

Bunların "DateTimeKind.Local" olarak kabul edilmesini istiyorsam ne olur?DateTime serializer yerel saate UTC gibi dönüyor. 'JsConfig.AssumeUtc = false;' çalışmadı. – ygormutti

+1

JSON için bu çalışır - JSV için bir eşdeğer var mı? – Cocowalla

5

Bpruitt-goddard çözümüne ince ayar yapın. Bütün krediler ona gider.

JsConfig<DateTime>.SerializeFn = time => new DateTime(time.Ticks, DateTimeKind.Local).ToString("o"); 
     JsConfig<DateTime?>.SerializeFn = 
      time => time != null ? new DateTime(time.Value.Ticks, DateTimeKind.Local).ToString("o") : null; 
     JsConfig.DateHandler = DateHandler.ISO8601; 

Yani hizmet yığınından çıkıyor herhangi bir tarih, bir ISO8601 tarih biçime zorunda kalacak ve gelen herhangi bir tarih ISO8601 dizesinden C# Bugüne kadar otomatik dönüştürülecektir.

İlgili konular