2015-01-26 8 views
7

मैं एक एफ # प्रोजेक्ट में रिकॉर्ड प्रकार का उपयोग कर रहा हूं कि मैं एक सी # वेबएपीआई परियोजना का खुलासा कर रहा हूं। उदाहरण के लिए:एफ #, जेसन, वेबएपी विकल्प प्रकार के सीरियलाइजेशन

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

this पद और this पद के आधार पर, json सही ढंग से serializaing है।

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

हालांकि, जब मैं रिकॉर्ड करने के लिए एक विकल्प के प्रकार में जोड़ने के लिए,

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

json unglued हो जाता है।

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

मैं json serializer बहुत चालाक मानों को लेकर इन/विकल्प से बाहर स्वचालित रूप से टाइप उन्हें डाल करने के लिए जा रहा है के साथ गैर विकल्प प्रकार रिकॉर्ड के रूप में ही देखने के लिए चाहते हैं।

क्या किसी ने इस अंत में कस्टम फॉर्मेटर बनाया है? क्या ओओबी कुछ है जो मुझे याद आ रही है?

धन्यवाद

उत्तर

5

एक कस्टम Json.NET कनवर्टर उस विकल्प प्रकार और एकल प्रकार भेदभाव यूनियनों (या कम से कम करने का दावा करता है, मैं ही एकमात्र विकल्प प्रकार मामले का परीक्षण) संभालती मौजूद है। यह here पाया जा सकता है।

उपयोग:

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

मैं कैसे एक सी # परियोजना में WebApiConfig को यह जोड़ना होगा:

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|]) 

कनवर्टर का उपयोग अन्य जवाब के रूप में एक ही है? क्या डिफॉल्ट कंट्रैक्ट रीसोलवर में कनवर्टर जोड़ने का कोई तरीका है? –

+0

एनएम -> इसे मिला। formatter.SerializerSettings.Converters.Add (नया IdiomaticDuConverter()); –

11

मैं कनवर्टर अन्य जवाब में जुड़े हुए की कोशिश की, और मैं अन्य दस के उत्पादन में जो विकल्प नहीं थे पसंद नहीं आया। इसके बजाय, आप सभी डीयू के बजाय विकल्प प्रकार पर केवल व्यवहार को बदलने का विकल्प चुन सकते हैं।

मुझे यह कनवर्टर मिला जो विकल्प विकल्प के लिए व्यवहार को केवल किसी भी विकल्प पर शून्य प्रदान करने के लिए व्यवहार को बदलेगा, अन्यथा मान। मूल कोड/लेखक जानकारी here मिल सकती है।

let json = JsonConvert.SerializeObject(myObj, new OptionConverter()) 
संबंधित मुद्दे