2016-04-18 17 views
0

JSON文字列を列挙型に逆シリアル化する方法を理解しようとしています。今は、シリアル化されたディクショナリをHttpPutメソッドに渡し、その文字列を逆シリアル化してリフレクションを使用してカスタムオブジェクトのフィールドを更新しています。ここで私がこれまで持っているものです。JSON文字列を列挙型にデシリアライズ

私はこのような辞書に値を入れている:私はシリアル化するためにJSONを使用してい

Dictionary<string, object> valuesToUpdate = new Dictionary<string, object>(); 
    valuesToUpdate.Add("Length", 64.0); //Length is a double 
    valuesToUpdate.Add("Confidence", SimpleConfidence.THREE); //Confidence is an enum 

はこのようなものです

string jsonString = JsonConvert.SerializeObject(valuesToUpdate); 

私はそれから取りますjsonStringを呼び出し、それをREST API PUT呼び出しに送信します。私の目標は、リフレクションを使用して辞書のKey値に基づいてカスタムオブジェクトのさまざまな変数を更新することです(この例では、customObject.ConfidenceおよびcustomObject.Lengthを更新します)。

PUTの呼び出しは、次のようにjsonStringをデシリアライズ:

Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString); 

私の計画はnewFieldsを反復処理し、customObjectのフィールドを更新するためにリフレクションを使用することです。今は、辞書が文字列や倍精度を検出したときに機能するコードをいくつか持っていますが、主に列挙型やクラスなど他の型の問題があります。ですから、基本的に、シリアル化されたjson辞書の文字列を取り込み、それを適切な型に変換して反映させるにはどうしたらいいですか?私が投稿した例では、「長さ」正しく更新されますが、「自信」は、このエラーがスローされます。これは

Object of type 'System.Int64' cannot be converted to type 'System.Nullable'1. 

ですが、私のHttpPut jsonString読み込む方法:だから、それを

[HttpPut("/test/stuff")] 
public string PutContact([FromBody]dynamic jsonString) 
{ 
     Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString); 
     foreach(var field in newFields) 
     { 
      Console.WriteLine("\nField key: " + field.Key); 
      Console.WriteLine("Field value: " + field.Value + "\n"); 

      PropertyInfo propInfo = typeof(CustomObject).GetProperty(field.Key); 
      var value = propInfo.GetValue(customObject, null); 
      propInfo.SetValue(customObject, field.Value, null); 
     } 
} 

を元の列挙型をInt64型にデシリアライズするのが好きなようです。列挙型のSimpleConfidenceの元の型としてそれを認識させるにはどうすればいいですか?

答えて

0

enum SimpleConfidenceの型識別は、シリアル化とデシリアライズの間に失われます。割り当て部分に特別な処理を追加することで、パッチを適用することができます。

//... 

foreach(var field in newFields) 
{ 
    // ... 

    PropertyInfo propInfo = typeof(CustomObject).GetProperty(field.Key); 
    var value = propInfo.GetValue(customObject, null); 

    PropertyInfo propInfo = null; 

    // handles TEnum 
    if (propInfo.PropertyType.IsEnum) 
    { 
     propInfo.SetValue(customObject, Enum.ToObject(propInfo.PropertyType, field.Value), null); 
    } 
    // handles TEnum? 
    else if (Nullable.GetUnderlyingType(propInfo.PropertyType)?.IsEnum == true) 
    // if previous line dont compile, use the next 2 
    //else if (Nullable.GetUnderlyingType(propInfo.PropertyType) != null && 
    //   Nullable.GetUnderlyingType(propInfo.PropertyType).IsEnum) 
    { 
     propInfo.SetValue(customObject, Enum.ToObject(Nullable.GetUnderlyingType(propInfo.PropertyType), field.Value), null); 
    } 
    else 
    { 
     propInfo.SetValue(customObject, field.Value, null); 
    } 

} 
+0

ありがとうございました!それは完璧に動作します! – Roka545

+0

JSON文字列をクラスに逆シリアル化する方法も知っていますか?私はここで別の投稿を作成しました:http://stackoverflow.com/questions/36728307/deserialize-json-string-into-class-with-reflection – Roka545