[英]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.