How to Deserialize Complex JSON file in SSIS into few columns - json

I have a JSON file that is pretty complex. Here is a snippet of my file:
JSON
"SKU": "12345",
"Status": {
"Health": "OK"
},
"Type": "ComputerSystem",
"Name": "Cartridge 1",
"Power": "Off",
"AssetTag": "12345",
"HostCorrelation": {
"IPAddress": [],
"HostMACAddress": [
"00:00:00:00:00:00",
"11:11:11:11:11:11"
]
},
"SerialNumber": "12345",
"Boot": {
"BootSourceOverrideSupported": [
"None",
"PXE",
"HDD",
"iSCSI",
"M.2",
"None"
],
"BootSourceOverrideTarget": "PXE",
"BootSourceOverrideEnabled": "Continuous"
}
Without showing all the classes here is the RootObject VS generates as code:
Paste JSON as Class
public class Rootobject
{
public string SKU { get; set; }
public Status Status { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public string Power { get; set; }
public string AssetTag { get; set; }
public Hostcorrelation HostCorrelation { get; set; }
public string SerialNumber { get; set; }
public Boot Boot { get; set; }
public Links links { get; set; }
public string UUID { get; set; }
public Bios Bios { get; set; }
public Oem Oem { get; set; }
public Memory Memory { get; set; }
public Availableaction[] AvailableActions { get; set; }
public string SystemType { get; set; }
public Processors Processors { get; set; }
public string Model { get; set; }
public string Manufacturer { get; set; }
}
I want to loop through multiple JSON files with this structure, and put them into a few columns such as (Section, Component, Property, and Value).
However, I have been having a hard time figuring this out. It would be simple to put each part into its own unique column.
The end result of my JSON example above may look like:
Goal SQL Output
The format doesn't have to be exact, but something along those lines. If there is a better way of doing this I am all ears.

I can tell you didn't post all of your classes because the RootObject has object references, but this is how you could start your code. This won;t get your data into the format you asked for, but it is how the serializer works.
string json = [Somehow get your json in to a string]
JavaScriptSerializer js = new JavaScriptSerializer();
var jRow = js.Deserialize<Rootobject>(json);
// now you have your entire JSON in one object.
//for the data you presented you will need a few outputs:
// let's start with the outermost:
Output0Buffer.AddRow();
Output0Buffer.SKU = jRow.SKU;
Output0Buffer.Health = jRow.Status.Health; //There is only one option here
Output0Buffer.Type = jRow.Type ;
Output0Buffer.Name = jRow.Name;
Output0Buffer.Power = jRow.Power ;
Output0Buffer.AssetTag = jRow.AssetTag ;
Output0Buffer.SerialNumber = jRow.SerialNumber ;
Output0Buffer.BootSourceOverrideTarget= jRow.Boot.BootSourceOverrideTarget ;
Output0Buffer.BootSourceOverrideEnabled= jRow.Boot.BootSourceOverrideEnabled;
//this is a new output of boot details linked by SKU
foreach(var dtl in jRow.Boot.BootSourceOverrideSupported)
{
OutputBootStuffBuffer.AddRow();
OutputBootStuffBuffer.SKU = JRow.SKU; //Making assumption that SKU is the key back
OutputBootStuffBuffer.BootSourceOverrideSupported = dtl.BootSourceOverrideSupported;
}

Related

Deserializing a Json array of objects in xamarin forms not working

I have a json api response of something like this:
[
{
"id": 1,
"accountnumber": "001303000023",
"accounttitle": "MEGA CROWN ",
"accountdesc": "MEGA CROWN ",
"productType": "Loan",
"prodname": "SME TERM LOAN ",
"bookbalance": -200000.00,
"effectivebalance": -200000.000000,
"currentbalance": -200000.0000
},
{
"id": 2,
"accountnumber": "1020145429",
"accounttitle": "MEGA CROWN",
"accountdesc": "CORPORATE ",
"productType": "Current",
"prodname": "CORPORATE CURRENT ACCOUNT ",
"bookbalance": 3000.00,
"effectivebalance": 23000.000000,
"currentbalance": 3000.0000
}
]
and here is my model class...
public class Balance
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("productType")]
public string AccountType { get; set; }
[JsonProperty("accountnumber")]
public string AccountNumber { get; set; }
public string accounttitle { get; set; }
public string accountdesc { get; set; }
public string prodname { get; set; }
public double effectivebalance { get; set; }
public double currentbalance { get; set; }
[JsonProperty("currentbalance")]
public double balance { get; set; }
public string AccountBalance { get; set; }
//public string AccountBalance
//{
// get
// {
// string bal = this.balance.ToString();
// var newBal = Math.Round(Convert.ToDouble(bal), 2).ToString("C", System.Globalization.CultureInfo.GetCultureInfo("en-us")).Replace("$", "N");
// return newBal;
// }
// set
// {
// AccountBalance = value;
// }
//}
public ImageSource WalletImage
{
get
{
var img = ImageAsset.WalletImage;
return img;
}
set
{
WalletImage = value;
}
}
public Transaction transactions { get; set; }
}
I have tried different approaches to deserialize but all is futile.
first method I tried is this:
List<Balance> userAccts = JsonConvert.DeserializeObject<List<Balance>>(jsonee);
But nothing seem to work. whenever I put a breakpoint on the above deserializer method, the call gets to the point of deserialization but doesn't go beyond that. It's always returning to the previous call then overtime will break the house.
Please any help will be deeply appreciated.
Note: I have even tried to add "{}" into the response using stringFormatter so as to be able to deserialize into a list but all proof futile.
I also tried to serialize the response then deserialize it again.
Wrap deserialise method into try catch and check what error you get exactly.
You have added "currentbalance" twice. One as property and other one as JsonPropertyAttribute with same name. Please keep only one.
public double currentbalance { get; set; }
[JsonProperty("currentbalance")]
public double balance { get; set; }
A member with the name 'currentbalance' already exists on
'StackQA_Console1.Balance'. Use the JsonPropertyAttribute to specify
another name.
Same code works for me after keeping single "currentbalance" property.

ASPNET Core - Json response stops at the related model

I have two classes that have relations between them. They are Market and Promotion classes. I'm facing a problem when I make a request. The json result stops when it comes to the relation.
The Market class:
public class Market : BaseModel
{
[Required]
public string Name { get; set; }
[Required]
public string Address { get; set; }
// GPS informations.
public double Latitude { get; set; }
public double Longitude { get; set; }
[Required]
public Guid PictureId { get; set; }
public Picture Picture { get; set; }
public List<Promotion> Promotions { get; set; }
}
The Promotion class:
public class Promotion : BaseModel
{
[Required]
public string Description { get; set; }
[Required]
public double Price { get; set; }
[Required]
public Guid PictureId { get; set; }
public Picture Picture { get; set; }
[Required]
public Guid MarketId { get; set; }
public Market Market { get; set; }
}
When I make the next request, I got an incomplete answer.
[HttpGet]
[AllowAnonymous]
public async Task<ActionResult<IEnumerable<Market>>> Get()
{
var markets = await _context.Markets
.Include(m => m.Owner)
.Include(m => m.Picture)
.Include(m => m.Promotions)
.ToListAsync();
return markets;
}
The response json stops when get at MarketId of the first promotion.
...
"pictureType": 0,
"pictureUrl": "https://superbarato.azurewebsites.net/api/Pictures/url/d6bc07a8-db55-4ee5-7342-08d73f6147e9",
"id": "d6bc07a8-db55-4ee5-7342-08d73f6147e9",
"createdAt": "2019-09-22T13:34:26.9367403",
"updatedAt": "0001-01-01T00:00:00",
"deletedAt": "0001-01-01T00:00:00",
"ownerId": "75c1f286-c07f-4e50-dda0-08d73f61058f",
"owner": null
},
"promotions": [
{
"description": "Açúcar Camil 1Kg",
"price": 5.0,
"pictureId": "e7af68b9-c053-4f4b-7344-08d73f6147e9",
"picture": null,
"marketId": "e2962be8-1a19-418a-6ce7-08d73f62308d"
How to get all the promotions?
In EF Core , you could configure Json.NET to ignore cycles that it finds in the object graph. This is done in the ConfigureServices(...) method in Startup.cs.
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
Another alternative is to decorate one of the navigation properties with the [JsonIgnore] attribute, which instructs Json.NET to not traverse that navigation property while serializing.
Reference :https://learn.microsoft.com/en-us/ef/core/querying/related-data#related-data-and-serialization
The problem of yours is that Market and Promotion types/instances are referencing each other and you got into a cycle serializing those two indefinitely. You may solve it by projecting database model without relationship to response model/structure to avoid that.
[HttpGet]
[AllowAnonymous]
public async Task<ActionResult<IEnumerable<MarketModel>>> Get()
{
var markets = await _context.Markets
.Select(m => new MarketModel {
Name = m.Name,
// Other properties needed to be serialized to response body
Promotions = m.Promotions.Select(p => new PromotionModel {
Description = p.Description,
// Other properties needed to be serialized to response body
MarketId = p.Market.Id
}
}
.ToListAsync();
return markets;
}
public class MarketModel
{
public string Name { get; set; }
// Other properties needed to be serialized to response body
public List<PromotionModel> Promotions { get; set; }
}
public class PromotionModel
{
public string Description { get; set; }
// Other properties needed to be serialized to response body
public Guid MarketId { get; set; }
}
Hope it helps.

Extracting JSON data using Newtonsoft in xamarin.android

Hello I am getting JSON data from server and i want to extract that JSON in Xamarin. How can i parse that JSON using NewTonSoft
below is the JSON responce i receive
[
{
"Id": 5,
"AlbumKey": "2REC2ZDSFK",
"ZipFillPath": "aaaa#gmail.com\\2REC2ZDSFK",
"NoOfPages": 3,
"EmailID": "aaaa#gmail.com"
}
]
This should be your Model
public class RootObject
{
public int Id { get; set; }
public string AlbumKey { get; set; }
public string ZipFillPath { get; set; }
public int NoOfPages { get; set; }
public string EmailID { get; set; }
}
Then
RootObject myObj = JsonConvert.DeserializeObject<RootObject>(json);
If your json is a List of objects, something like
List<RootObject> myListObj = JsonConvert.DeserializeObject<List<RootObject>>(json);
public class yourClass
{
public int Id { get; set; }
public string AlbumKey { get; set; }
public string ZipFillPath { get; set; }
public int NoOfPages { get; set; }
public string EmailID { get; set; }
}
Considering this as your model class you can
var responseText= JsonConvert.DeserializeObject<yourClass>(jsonResponse);
Then depending on if its a list or a not you can get the data from it
In case you are unable to find the class what you can do is check if the namespace of your current class and that class is the same.

Parse Json to List

I want to parse a json to List how can we do that. I have tried the following code but it didnt worked
Dictionary<string, object> pGateways=(Dictionary<string,object>)Json.JsonParser.FromJson(jsonString);
List<object> creditOptions = new List<object>();
creditOptions = (List<object>)pGateways;
And after getting it int list i want to loop through it
Here is my sample json
{
"MessageCode": "CS2009",
"Status": "Y",
"ErrorCode": "0",
"ErrorDescription": "Success",
"account":
{
"card":
[
{
"cardend": "asd",
"token": "aads",
"cardstart": "asdad",
"accounttype": "asda",
"cardnetwork": "as",
"issuer": "asd",
"customername": "a",
"expdate": "04/2018"
},
{
"cardend": "asda",
"token":"adssadsa",
"cardstart": "asd",
"accounttype": "asd",
"cardnetwork": "asd",
"issuer": "asda",
"customername": "asd",
"expdate": "03/2016"
}
],
"bank": []
}
}
The best option could be to use the JsonConvert in order to parse Json into a List.
Reference: JSON Parsing in Windows Phone
You can use Json.Net.
To install Json.NET use NugetGallery : Json.net Nugets Gallery
And you can use json2Csharp.com for generate c# classes from json
The JSON string you posted is not suitable for straight-forward deserialization to List. The easiest thing to do is use the online JSON 2 CSharp tool to generate classes and deserialize the json string to it. Here is an example of the generated classes:
public class Card
{
public string cardend { get; set; }
public string token { get; set; }
public string cardstart { get; set; }
public string accounttype { get; set; }
public string cardnetwork { get; set; }
public string issuer { get; set; }
public string customername { get; set; }
public string expdate { get; set; }
}
public class Account
{
public List<Card> card { get; set; }
public List<object> bank { get; set; }
}
public class RootObject
{
public string MessageCode { get; set; }
public string Status { get; set; }
public string ErrorCode { get; set; }
public string ErrorDescription { get; set; }
public Account account { get; set; }
}
And here is the logic for deserialization:
var root = JsonConvert.DeserializeObject<RootObject>(jsonStr);
where the jsonStr variable holds the json string you posted.
You need to use json2csharp tool to generate classes and deserialize the JSON string to list.
Here is the Classes generated from your JSON string.
public class Card
{
public string cardend { get; set; }
public string token { get; set; }
public string cardstart { get; set; }
public string accounttype { get; set; }
public string cardnetwork { get; set; }
public string issuer { get; set; }
public string customername { get; set; }
public string expdate { get; set; }
}
public class Account
{
public List<Card> card { get; set; }
public List<object> bank { get; set; }
}
public class RootObject
{
public string MessageCode { get; set; }
public string Status { get; set; }
public string ErrorCode { get; set; }
public string ErrorDescription { get; set; }
public Account account { get; set; }
}
and Deserialize your JSON object using JsonConvert,
Suppose e.result is your JSON string then
var rootObject = JsonConvert.DeserializeObject<RootObject>(e.Result);
foreach (var blog in rootObject.Card)
{
//access your data like this- `blog.cardend;` or `blog.token;`
}

Cannot Deserialise Json array into type string

Following id my piece of code which deserialise Json string.
response = "{\"success\":\"yes\",\"error\":\"\",\"message\":\"\",\"arguments\":[{\"id\":\"72820\",\"rowNo\":\"1\",\"userId\":\"40\",\"entityId\":\"3486\",\"value\":\"search Panel\",\"typeCategory\":\"3\"}]}";
erpAPIResponse basicResponse = JsonConvert.DeserializeObject<erpAPIResponse>(response);
Result is JSON string which is deserialised into erpAPIResponse.
My erpAPIResponse is as follows:
public string success { get; set; } // getting and setting the success
public string error { get; set; } // getting and setting the error
public string message { get; set; } // getting and setting the message
public string arguments { get; set; } // getting and setting the arguments
// public string result { get; set; }
I have verify json through JSON Lint and it is saying it is valid JSON string. So why i am getting this errorr?
As your json structure is like below:
{
"success": "yes",
"error": "",
"message": "",
"arguments": [
{
"id": "72820",
"rowNo": "1",
"userId": "40",
"entityId": "3486",
"value": "search Panel",
"typeCategory": "3"
}
]
}
Here you cannot deserialize the arguments array in a string. So you need to redefine the erpAPIResponse class like below using json2csharp utility:
public class erpAPIResponse
{
public string success { get; set; }
public string error { get; set; }
public string message { get; set; }
public List<Argument> arguments { get; set; }
}
public class Argument
{
public string id { get; set; }
public string rowNo { get; set; }
public string userId { get; set; }
public string entityId { get; set; }
public string value { get; set; }
public string typeCategory { get; set; }
}
Now you should have no problem deserializing with your original statements:
response = "{\"success\":\"yes\",\"error\":\"\",\"message\":\"\",\"arguments\":[{\"id\":\"72820\",\"rowNo\":\"1\",\"userId\":\"40\",\"entityId\":\"3486\",\"value\":\"search Panel\",\"typeCategory\":\"3\"}]}";
erpAPIResponse basicResponse = JsonConvert.DeserializeObject<erpAPIResponse>(response);