2

シナリオは、ネットワークからJSON文字列を受け取って、対応する正しいレコードタイプに逆シリアル化します。F#JSON文字列を正しいレコードタイプに逆シリアル化する

JSON文字列のいずれかとすることができる:

(1)"{"a":"some text"}"又は

(2)"{"b":1}"

値は異なるかもしれないが、フィールドのフォーマットは、タイプ1またはタイプ2に対応する次のいずれか

:不明な文字列を受信した場合、私は正しいレコード型のインスタンスを取得しようとしている
type Type1 = {a:string} 
type Type2 = {b:int} 
// Contents of a string might be like (1) or like (2), but we don't know which one 
let someJsonString = "..." 

let obj = JsonConvert.DeserializeObject(someJsonString) 

最後の行はObject型のオブジェクトを返します。

match obj with 
| :? Type1 as t1 -> printfn "Type1: a = %A" t1.a 
| :? Type2 as t2 -> printfn "Type2: b = %A" t2.b 
| _ -> printfn "None of above" 

ここで「上記のいずれも、」印刷されない:タイプを決定しないその上にパターンマッチングを用い

私はいくつかのタイプを示す使用してオブジェクトをデシリアライズ:

JsonConvert.DeserializeObject<Type1>(someJsonString) 

パターンマッチングが働いて、印刷されています

Type1: a = <the value of a> 

しかし、私ができるので、私の場合には動作しないこと」 JSON文字列が未知のコンテンツの種類を事前に知っています。

文字列の内容に基づいて正しいレコードタイプにJSON文字列を逆シリアル化する方法はありますか?

注:必要に応じて、文字列が送信される側でシリアル化されると、この文字列の一部として型の名前を送信できます。しかし、次に、 "Type1"や "Type2"のようなタイプの名前を持つTypeタイプのインスタンスを取得する方法はありますか?

タイプの完全修飾名はマシンによって異なりますので、可能かどうかはわかりません。私。一台のマシンは、タイプ1として指定されています:

"FSI_0059+Test1, FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" 

そして別の一つとして:

"FSI_0047+Test1, FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" 

答えて

2

あなたは追加の型情報なしで一般的にこれを行うことはできません。型はシリアル化するときに指定する必要があります。そのため、逆シリアル化するときに型が読み取られる可能性があります。得られたJSONは、正しいタイプにデシリアライズするように、serialzing場合

Newtonsoft.JsonTypeNameHandlingoption that you can setを有しています。

はここで完全な例です:

let instance = { a = 10 } 
let settings = new JsonSerializerSettings(TypeNameHandling = TypeNameHandling.All) 
let json = JsonConvert.SerializeObject(instance, settings) 
let retrieved = JsonConvert.DeserializeObject(json, settings) 
+0

オブジェクトが1台のマシン上で連載され、別の1に直列化復元されている場合、これは動作しないでしょう。たとえば、あるマシンで試してみました。オブジェクトを正しいタイプにデシリアライズすることができます。しかし、別のマシンでそれを逆シリアル化すると、タイプの完全修飾タイプ名は異なります。これは、たとえば「FSI_0047 + Type1」のさまざまなバリエーションが接頭辞に付いているためです。毎回、同じタイプのアセンブリ名が同じであることを確認する方法を知っていますか? – experimenter

+1

あなたがFSIを使用しているからです。型名が生成されます。それ以外の場合は、2つのマシン間でアセンブリを共有し、 '#r'で参照してください。 – Asti

+0

ありがとう、私はこれが動作すると思います – experimenter

関連する問題