簡體   English   中英

在C#中反序列化JSON值數組

[英]Deserialize JSON array of values in C#

我在使用此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表中的一列中)。 這些腳本具有相似的結構-但不相同。 因此,我想到了C#分辨率,這將在搜索我需要的參數。 對於沒有這些參數的json腳本,C#代碼會將空值放在正確的輸出列中。

這是我的輸出列:-agreeWithCompleteAnalysis -inOtherSystem -investmentInterest -projectionId -insuredAgentFflag -nonOfferedProducts

我了解到,我的課程結構錯了-我會加以改善。 但是我有一個疑問-是否可以准備僅處理我需要的這些參數的c#代碼結構?

最后,我想將結果放入數據庫。 例如,如果nonOfferedProducts屬性將具有3個值(並非總是!),我想將3條記錄發送到我的數據庫(nonOfferedProducts列有3個不同的值,其余列有3個相同的值-agreeWithCompleteAnalysis,inOtherSystem等)。

我希望現在會清楚。 非常感謝你的幫助!

Ĵ

使用https://quicktype.io並粘貼json,它將生成c#模型和序列化程序代碼。

正如我在評論中所說,您的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; }
}

一旦模型正確,則反序列化對於給定的示例對我來說就可以正常工作(我在單元測試中做到了這一點,但是假設您的字符串與您的示例匹配,這應該就可以了)

//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());

斷言傳遞-通過給定的示例,此代碼愉快地獲取NonOfferedProducts屬性中的字符串列表。

顯然,如果您不能依賴JSON的一致性(無論是結構還是結構形式),都會遇到問題,但這是另一個問題。

要回答您的問題2),您將收到對象引用錯誤,因為BasicDataClass.nonOfferedProducts為null,並且您嘗試對其進行迭代,這可能是您發送錯誤的json的原因,而JavaScriptSerializer無法將其反序列化。

您的第三個問題,您始終可以使用在線驗證的json驗證程序來驗證json,例如https://jsonformatter.org/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM