2017-12-15 30 views
0

私は、このJSONスクリプトでいくつかの困難を持っている:逆シリアル化JSON配列は

{ 
    "insured_agent_flag": "a", 
    "id": "1", 
    "agent": { 
    "fullName": "John Travolta", 
    "mobileNumberPdf": "+987654321", 
    "mobileNumber": "", 
    "identityCard": { 
     "identityCardExpirationDate": null 
    }, 
    "secondIdentityCard": { 
     "identityCardExpirationDate": null 
    }, 
    "notes": {}, 
    "sign": "ADVANCED" 
    }, 
    "basicData": { 
      "personType": "PERSON", 
      "agreeWithCompleteAnalysis": false, 
      "investmentInterest": false 
    }, 
    "nonOfferedProducts": [ 
    "PROD_A", 
    "PROD_B", 
    "PROD_C" 
    ] 
} 

私はこのスクリプトからいくつかのパラメータを取得し、SQL Serverのテーブルに入れたいと思います。 はそれを行うためには、私が使用して変換https://mycontraption.comで共有するC#のスクリプト:「標準」の場合

using System; 
using System.Data; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.SqlServer.Dts.Pipeline.Wrapper; 
using Microsoft.SqlServer.Dts.Runtime.Wrapper; 
using System.Web.Script.Serialization; 
using Microsoft.SqlServer.Dts.Pipeline; 

namespace SC_c7e2d8c3918d46a5a07a1b438ddc7642 
{ 
public class BasicData 
{ 
    public string agreeWithCompleteAnalysis { get; set; } 
    public string inOtherSystem { get; set; } 
    public string investmentInterest { get; set; } 
} 

public class ParentObject 
{ 
    public BasicData BasicData { get; set; } 
    public int id { get; set; } 
    public string insured_agent_flag { get; set; } 
    public IEnumerable<string> NonOfferedProducts { get; set; } 
} 

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute] 
public class ScriptMain : UserComponent 
{ 
    public override void Input0_ProcessInputRow(Input0Buffer Row) 
    { 
     JavaScriptSerializer js = new JavaScriptSerializer(); 

     // Give the input column a variable to make it easier to reference. 
     BlobColumn combinedColumn = Row.parameterscon; 

     // Convert from blob to string 
     string reviewConverted = System.Text.Encoding.ASCII.GetString(combinedColumn.GetBlobData(0, Convert.ToInt32(combinedColumn.Length))); 

     // Deserialize the string 
     ParentObject obj = js.Deserialize<ParentObject>(reviewConverted); 


     var rows = obj.NonOfferedProducts.ToList(); 

     Row.agreeWithCompleteAnalysis = obj.BasicData.agreeWithCompleteAnalysis; 
     Row.inOtherSystem = obj.BasicData.inOtherSystem; 
     Row.investmentInterest = obj.BasicData.investmentInterest; 
     Row.projectionid = obj.id; 
     Row.insuredagentflag = obj.insured_agent_flag; 

     //Row.nonOfferedProducts = 

    } 
} 
} 

それが正常に動作オブジェクトを、しかし、配列「nonOfferedProducts」に問題があります。コンパイル後、私はエラーを受け取ります: "オブジェクト参照がオブジェクトのインスタンスに設定されていません"。

ここに私の質問があります: 1. C#スクリプトで 'nonOfferedProducts'配列をどのように扱うべきですか? 2.前述のエラーが発生するのはなぜですか? 3.残念ながら、jsonスクリプトには中カッコのようなエラーがある可能性があります。私はそれをどのように扱うべきですか?

ありがとうございました!


お返事ありがとうございます。あなたのコメントによると、私はあなたにもっと説明を与えようとします: 1.この記事で追加したjsonスクリプト - スクリプト全体のほんの一部です。完全なスクリプトには、さまざまなパラメータがあります。さらに、私のC#コードは約40.000個のjsonスクリプト(SQL Serverのテーブルに1列で格納されています)をスキャンする必要があります。これらのスクリプトは類似の構造を持っていますが、同じではありません。 私はC#の解像度について考え、必要なパラメータを探します。これらのパラメータを持たないjsonスクリプトの場合、C#コードは正しい出力列にヌルを入れます。ここで

が私の出力列です: -agreeWithCompleteAnalysis -inOtherSystem -investmentInterest -projectionId -insuredAgentFflag -nonOfferedProducts

私は理解し、私のクラスの構造が間違っていた - 私はそれを改善します。 しかし、私は1つの疑問を持っています - 必要なこれらのパラメータだけを処理するC#コード構造を準備することは可能ですか?

最後に、結果をデータベースに保存したいと思います。 たとえば、nonOfferedProductsプロパティに3つの値(必ずしも!)がない場合、私のデータベーステーブルに3レコード(nonOfferedProductsカラムの3つの異なる値と残りのカラムの同じ値-agreeWithCompleteAnalysis、inOtherSystemなど) 。

今はっきりすることを願っています。 ご協力いただきありがとうございます!

J

+0

ループを実行すると予想されるアルゴリズムの英語の説明であるコメントを追加するコードを編集してください。論理的な意味がなく、あなたの意図が書かれたものから推測できない場合 –

+0

C#クラスがJSONモデルと一致しません - 'basicData'はメインオブジェクト内の' object'です。 'agreeWithCompleteAnalysis'はこのオブジェクトのプロパティです。 'nonOfferedProducts'は、親オブジェクトの配列プロパティです。デシリアライズがこれをどのように処理しているのかよく分かりませんが、 'nonOfferedProducts'プロパティを持たない' basicData'オブジェクトだけを取り出していると仮定します。したがって、nullです。しかし、基本的な答えは単に 'nonOfferedProducts'が参照される前にヌルであるかどうかを確認することです - しかし、あなたの問題は本当にJSONとクラスの間の不一致だと思います。 – GPW

+0

JSONが不正な形式の場合、それを拒否したり、適切なビットがあるかどうかにかかわらず、自分のパーサを最初から書き出して、必要な値を引き出す必要があります。個人的には、一貫性のある有効なデータを主張するか、問題を求めていると思います。 JSONは定義によるとJSONではなく、見た目だけのテキストです。 – GPW

答えて

1

私は私のコメントで述べたように、あなたのC#のモデルは、JSONオブジェクトと一致していません。

モデルは、より良い実際のJSONを反映するために、様々なネストされたオブジェクトの構成されていたならば、あなたはより多くの幸運があります:モデルが正しいたら

public class IdentityCard 
{ 
    public DateTime? IdentityCardExpirationDate { get; set; } 
} 

public class Notes 
{ 
    //No idea what should be in here... 
} 
public class BasicData 
{ 
    public string PersonType { get; set; } 
    public bool AgreeWithCompleteAnalysis { get; set; } 
    public bool InvestmentInterest { get; set; } 
} 

public class Agent 
{ 
    public string FullName { get; set; } 
    public string MobileNumberPdf { get; set; } 
    public string MobileNumber { get; set; } 
    public IdentityCard IdentityCard { get; set; } 
    public IdentityCard SecondIdentityCard { get; set; } 
    public Notes Notes { get; set; } 
    public string Sign { get; set; } 
} 

//Note: THIS is the actual class that matches the JSON sample given. 
public class ParentObject 
{ 
    public string insured_agent_flag { get; set; } 
    public int Id { get; set; } 
    public Agent Agent { get; set; } 
    public BasicData BasicData { get; set; } 
    public IEnumerable<string> NonOfferedProducts { get; set; } 
} 

は、その後、デシリアライズが与えられたと私のために正常に動作しますこのコードは喜んで与えられた例とNonOfferedProductsプロパティに文字列のリストを取得する - 例(私はユニットテストでこれをやったが、あなたの文字列はあなたの例に一致し、これは問題ないはずと仮定した場合)

//get json 
string json = @" 
    { 
     ""insured_agent_flag"": ""a"", 
     ""id"": ""1"", 
     ""agent"": { 
     ""fullName"": ""John Travolta"", 
     ""mobileNumberPdf"": ""+987654321"", 
     ""mobileNumber"": """", 
     ""identityCard"": { 
      ""identityCardExpirationDate"": null 
     }, 
     ""secondIdentityCard"": { 
      ""identityCardExpirationDate"": null 
     }, 
     ""notes"": {}, 
     ""sign"": ""ADVANCED"" 
     }, 
     ""basicData"": { 
       ""personType"": ""PERSON"", 
       ""agreeWithCompleteAnalysis"": false, 
       ""investmentInterest"": false 
     }, 
     ""nonOfferedProducts"": [ 
     ""PROD_A"", 
     ""PROD_B"", 
     ""PROD_C"" 
     ] 
    }"; 

var js = new JavaScriptSerializer(); 
ParentObject obj = js.Deserialize<ParentObject>(json); 

//do things... 
var rows = obj.NonOfferedProducts.ToList(); 
Assert.AreEqual(3, rows.Count); 
Assert.AreEqual("PROD_A", rows.First()); 

ザ・合格主張します。

JSONの一貫性に頼ることができないのであれば、明らかに問題はありますが、それは別の問題です。

+0

ありがとうございます。私はクラスの構造を改善しました.C#コードは私のポストで更新されています。しかし、あなたのコードが私の問題を解決するかどうかは分かりません。追加の説明を見ていただけますか?ありがとうございました! – jonathan

+0

@jonathan:あなたの質問にいくつかのコメントを追加しました。 – GPW

0

BasicDataClass.nonOfferedProductsがnullであり、繰り返し処理しようとしているため、2)あなたはオブジェクト参照エラーが発生しています。JavaScriptSerializerが間違ったjsonを送信している可能性があります脱揮する。

あなたの第三の質問あなたは常に使用https://quicktype.iohttps://jsonformatter.org/

2

のようなオンラインがあるJSONバリデーターとペーストJSONを使ってJSONを検証することができ、それは、C#のモデルとシリアライザコードを生成します。

+0

upvoteこれは私がよく知らないクールな小さなツールです - 非常に便利で私はそれをブックマークします – GPW

関連する問題