2015-01-26 22 views
7

C# WebApi projesine maruz bıraktığım bir F # projesinde kayıt türleri kullanıyorum. Örneğin: this yazılan ve this yayına göre F #, Json, WebApi Seçenek Türlerinin Serileştirilmesi

type Account = {Amount:float; Number:int; Holder:string} 

, json doğru serializaing edilir. Ancak

{"Amount":100.0,"Number":1,"Holder":"Homer"} 

, ben kaydına bir seçenek türü eklemek

type Account = {Amount:float; Number:int; Holder:string option } 

json unglued olur.

{"Amount":100.0,"Number":1,"Holder":{"Case":"Some","Fields":["Homer"]}} 

Ben json serileştirici değerlerini alıp seçeneği dışında otomatik yazın içinde/koymak için yeterince akıllı olmak dışı opsiyon tipi kaydı olarak aynı görünür isterim.

Bu amaçla herhangi bir özel biçimlendirici oluşturmuş olan var mı? Kaybettiğim bir OOB var mı?

Teşekkür

cevap

5

(veya en azından iddia, ben tek seçenek tipi durumda test) mevcut mu opsiyon türleri ve tek tip ayrımcılık sendikaları kolları Özel bir Json.NET dönüştürücü. here bulunabilir.

Kullanımı:

let act = {Amount= 100.0; Number= 1; Holder= Some "Homer"} 
let json = JsonConvert.SerializeObject(act, new IdiomaticDuConverter()) 
+0

nasıl C# Projesi WebApiConfig bu eklersiniz: dönüştürücü kullanarak

open System open Microsoft.FSharp.Reflection open Newtonsoft.Json open Newtonsoft.Json.Converters type OptionConverter() = inherit JsonConverter() override x.CanConvert(t) = t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<option<_>> override x.WriteJson(writer, value, serializer) = let value = if value = null then null else let _,fields = FSharpValue.GetUnionFields(value, value.GetType()) fields.[0] serializer.Serialize(writer, value) override x.ReadJson(reader, t, existingValue, serializer) = let innerType = t.GetGenericArguments().[0] let innerType = if innerType.IsValueType then (typedefof<Nullable<_>>).MakeGenericType([|innerType|]) else innerType let value = serializer.Deserialize(reader, innerType) let cases = FSharpType.GetUnionCases(t) if value = null then FSharpValue.MakeUnion(cases.[0], [||]) else FSharpValue.MakeUnion(cases.[1], [|value|]) 

diğer cevap aynıdır? DefaultContractResolver'a dönüştürücü eklemenin bir yolu var mı? –

+0

NM -> anladım. formatter.SerializerSettings.Converters.Add (yeni IdiomaticDuConverter()); –

11

diğer yanıtında bağlantılı dönüştürücü çalıştı ve Opsiyon değildi diğer DÜ'lerin çıkışını gibi değildi. Bunun yerine sadece tüm DU'lardan ziyade Seçenek türündeki davranışı değiştirmeyi tercih edebilirsiniz.

Ben, aksi değerini Yok seçeneğini boş işlemek için opsiyon türü için sadece davranışını değiştirecek bu dönüştürücü buldum. Orijinal kod/yazar bilgisi here bulunabilir.

let json = JsonConvert.SerializeObject(myObj, new OptionConverter())