Newtonsoft.Json.Linq.JObject.GetValue( "[キー]")。ToObject <DataTableの>に関連する問題

 

我々(「[キー]」)。ToObject <データテーブル> Newtonsoft.Json.Linq.JObject.GetValue容易データテーブルデータ形式にノードjオブジェクトのオブジェクトを変換する方法です。このような使用は問題ではなかったです。しかし、最近になって、私たちはいくつかのケースでは、このデータ変換は、実際にいくつかの問題、あるいはエラーを持っていることがわかりました。シナリオ:

1.ときに同様の時間以下のデータソース。第2の変換データを作成する、その結果、ノードデータテーブルデータフォーマットデフォルトABC整数フィールドにデータを変換するとき、50.11失う精度は、50の整数になります

"{\" データ\ ":[{\" ABC \ ":50}、{\" ABC \ ":50.01}]}"

2.データソースは次のようです。第二のデータ型がINTに変換する際には、エラーになります。

"{\" データ\ ":[{\" ABC \ ":50}、{\" ABC \ ":\" XYZ \ "}]}"

 

ToObjectのJsonSerializerパラメータを使用する必要があります。シリアライザ方法を書き換えることにより、所望の効果を達成するように、列のデータ・タイプを指定します。

パブリッククラスCustomDataTableConverter:DataTableConverter 
{ 
    プライベート静的ボイドCreateRow(JsonReaderリーダ、データテーブルDT)
    { 
        のDataRow行= dt.NewRow()。
        reader.Read(); 

        (reader.TokenType == JsonToken.PropertyName)一方
        { 
            ストリングCOLUMNNAME =(文字列)reader.Value。
            reader.Read(); 
            DataColumnカラム= dt.Columns [COLUMNNAME]。
            IF(カラム== NULL)
            { 
                タイプcolumnDataType = GetColumnDataType(リーダー)。
                カラム=新規のDataColumn(COLUMNNAME、columnDataType)。
                dt.Columns.Add(列);
            }
            IF(column.DataType == typeof演算(データテーブル))
            { 
                 IF(reader.TokenType == JsonToken.StartArray)
                 { 
                     reader.Read()。
                 } 
                 データテーブル表=新しいデータテーブル()。
                 一方、(reader.TokenType = JsonToken.EndArray!)
                 { 
                     CreateRow(リーダー、表)。
                     reader.Read(); 
                 } 
                 行[COLUMNNAME] =表。
            } 
            そうであれば(column.DataType.IsArray &&(column.DataType!= typeof演算(バイト[])))
            { 
                であれば(reader.TokenType == JsonToken.StartArray)
                 { 
                     reader.Read()。
                 } 
                 リスト<オブジェクト>リスト=新しいリスト<オブジェクト>(); 
                 (!reader.TokenType = JsonToken.EndArray)一方
                 { 
                     list.Add(reader.Value)。
                     reader.Read(); 
                 } 
                 アレイdestinationArray = Array.CreateInstance(column.DataType.GetElementType()、list.Count)。
                 Array.Copy(list.ToArray()、destinationArray、list.Count)。
                 行[COLUMNNAME] = destinationArray。
            } 
            { 
                オブジェクトヴァル= DBNull.Valueの。
                IF(!reader.Value = NULL)
                { 
                    IF(column.DataType == typeof演算(文字列))
                    { 
                         ヴァル= reader.Value.ToString()。
                    } 
                    { 
                        IF(string.IsNullOrEmpty(reader.Value.ToString()))
                        { 
                            ヴァル= DBNull.Valueの。
                        } 
                        { 
                            ヴァル= Convert.ChangeType(reader.Value、column.DataType)。
                        }
                    } 
                    行[COLUMNNAME] =ヴァル。
                } 
                reader.Read()。
            }     
            row.EndEdit()。
            dt.Rows.Add(行)。
        } 
    }   

    プライベート静的型GetColumnDataType(JsonReaderリーダ)
    { 
        JSONTokenをtokenType = reader.TokenType。
        スイッチ(tokenType)
        { 
            ケースJsonToken.StartArray:
                reader.Read(); 
                IF(!reader.TokenType = JsonToken.StartObject)
                { 
                     リターンGetColumnDataType(リーダ).MakeArrayType(); 
                }
                typeof演算(DataTableの)を返します。
            //この場所は数値型の特別な処理を必要とします。あなたが数値カラムを特定できる場合は、精度の損失を防ぐために、二重の代わりに使用することができます。列タイプは、文字列型の文字列、その後、使用、エラーを防止するためにデータの変換である場合      
            :ケースJsonToken.Integer
                ;戻りtypeof演算(ダブル)
            :ケースJsonToken.Float
            ケースJsonToken.String:
            ケースJsonToken.Boolean:
            ケースJsonToken.Date:
            ケースJSONTokenをします。バイト:
                リターンreader.ValueType;
            ケースJsonToken.Null:
            ケースJsonToken.Undefined:
                リターンtypeof演算(文字列);
        }
        スロー新しい新JSONException($ "予期しないトークンJSON読書のDataTable間:TokenType {}");
    }

    プライベートの静的な無効MakeTableSchema(文字列スキーマ、データテーブルDT)
    { 
        場合(string.IsNullOrEmpty(スキーマ)&& DT = nullを!)
        { 
            文字列[] colinfos = schema.Trim( ' ')スプリット('、')。
            foreachの(colinfosの文字列COLINFO)
            { 
                文字列[]インフォメーション= colinfo.split( '|')。
                (もし!dt.Columns.Contains(インフォ[0]))
                { 
                    dt.Columns.Add(インフォ[0]、Type.GetType( "システム。" +情報[i]の)); 
                } 
            } 
        } 
    }
 
    公共オーバーライドオブジェクトReadJson(JsonReaderリーダー、タイプobjectTypeに、オブジェクトexistingValue、JsonSerializerシリアライザ)
    { 
        データテーブルDT = existingValueデータテーブルとして、 
                IF((文字列)reader.Value == "スキーマ")
                { 
                    reader.Read()。
            DT =(objectTypeに== typeof演算(DataTableの))?新しいのDataTable():((DataTableの)Activator.CreateInstance(objectTypeに)); 
        } 
        IF(reader.TokenType == JsonToken.PropertyName)
        { 
            dt.TableName =(文字列)reader.Value。
            reader.Read(); 
        } 
        IF(reader.TokenType == JsonToken.StartObject)
        { 
            reader.Read()。
            (reader.TokenType == JsonToken.PropertyName)一方
            { 
                    MakeTableSchema((文字列)reader.Value、DT)。
                    reader.Read(); 
                } 
                ((文字列)reader.Value == "TABLENAME")場合 
                { 
                    reader.Read()。
                    dt.TableName =(文字列)reader.Value。
                    reader.Read(); 
                } 
                他((文字列)reader.Value == "DATA")であれば
                { 
                    reader.Read()。
                    IF(reader.TokenType == JsonToken.StartArray)
                    { 
                        reader.Read()。
                    }
                    一方、(reader.TokenType = JsonToken.EndArray!)
                    { 
                         CreateRow(リーダー、DT)。
                         reader.Read(); 
                     } 
                }
            } 
            reader.Read()。
        } 
        他(reader.TokenType == JsonToken.StartArray)であれば
        { 
            reader.Read()。
            一方、(!reader.TokenType = JsonToken.EndArray)
            { 
                (リーダー、dt)を作成します。
                reader.Read(); 
            } 
        } 
        dtを返します。
    }
        StringBuilderのSB =新しいStringBuilderの(); 
        foreachの(table.ColumnsでDataColumnsの列)
 
    公共オーバーライドボイドWriteJson(JsonWriterライター、オブジェクト値、JsonSerializerシリアライザ)
    { 
        データテーブル表=(データテーブル)値。
        DefaultContractResolver contractResolver = serializer.ContractResolver DefaultContractResolverとして。
        { 
            sb.Append(column.ColumnName + "|" + column.DataType.Name + ""); 
        } 
        writer.WriteStartObject()。
        writer.WritePropertyName( "SCHEMA"); 
        serializer.Serializer(作家、sb.ToString()); 
        writer.WritePropertyName( "TABLENAME")。
        serializer.Serialize(作家、table.TableName)。
        writer.WritePropertyName( "DATA"); 
        writer.WriteStartArray(); 
        foreachの(table.RowsでのDataRow行)
        { 
            writer.WriteStartObject(); 
            foreachの(row.Table.ColumnsでのDataColumn列)
            {
                 IF((serializer.NullValueHandling!= NullValueHanding.Ignore)||((行[列]!= NULL)&&(行[列]!= DBNull.Valueの)))
                 { 
                     writer.WritePropertyName((contractResolver!= NULL)? contractResolver.GetResolvedPropertyName(column.ColumnName):column.ColumnName); 
                     serializer.Serialize(ライター、行[列])。
                 } 
            } 
            writer.WriteEndObject()。
        } 
        writer.WriteEndArray()。
        writer.WriteEndObject(); 
    } 
}                                        

 

メソッドを呼び出します

JsonSerializerシリアライザ=新しいJsonSerializer(); 
serializer.Converts.Add(新しいCustomDataTableConverter()); 
JObject.GetValue( "[キー]")ToObject <データテーブル>(シリアライザ)。

 

そのようなデータは、比較的正確にデータテーブルに変換することができます。

 

おすすめ

転載: www.cnblogs.com/herohh/p/11951293.html