C# ASP.net - How to use Json object auto mapping in models - c#

How I can create models to auto map this json object response in Class with root models.
I create the models with json convert to c# it's return null values
This is my json object response.
{
"factivityactual": [],
"fkpi": [
{
"note_id": "1DAE3D4A74A7DE91472588D20024C114",
"sql_id": "test",
"RefKPI_Detail": "test",
"Refdocid": "144149A40134720B472588D20024C110",
"criterion_1": "test",
"criterion_2": "test",
"criterion_3": "test",
"criterion_Type": "2",
"criterion_4": "test",
"criterion_5": "test"
}
],
"factivityplan": [
{
"Q2_sum_Comment": "",
"sql_id": "",
"Q1_sum_Comment": "",
"Activity": "TEST",
"Q2_sum_Budget": "",
"Month": "01",
"Q4_sum_Comment": "",
"Q3_sum_Comment": "",
"Order": 0,
"M_Budget1": 0,
"M_Budget2": 0,
"TypeActivity": "test",
"M_Budget3": 0,
"M_Budget4": 0,
"M_Budget5": 0,
"M_Budget6": 0,
"Q4_sum_Budget": "",
"Unit_T": "test",
"M_Budget10": 0,
"M_Budget11": 0,
"OwnerProject": "ทดสอบ~ทดสอบ~ทดสอบ",
"M_Budget12": 0,
"Q3_sum_Budget": "",
"Detail": "",
"MainNameActivity": "test",
"M_Comment10": "test",
"M_Comment11": "test",
"M_Comment12": "test",
"Q1_sum_Budget": "",
"DetailOwnerName": "ทดสอบ~ทดสอบ~ทดสอบ",
"RefDocID": "144149A40134720B472588D20024C110",
"M_Budget7": 0,
"M_Budget8": 0,
"Budget": 0,
"FaceName": "test",
"M_Budget9": 0,
"Budget2": 0,
"note_id": "B6783436311E7280472588D20024C115",
"M_Comment9": "test",
"sumDetailP": "test",
"M_Comment7": "test",
"M_Comment8": "test",
"M_Comment5": "test",
"M_Comment6": "test",
"M_Comment3": "test",
"M_Comment4": "test",
"NameActivity": "test",
"M_Comment1": "test",
"M_Comment2": "test",
"criterion_Type": "2"
}
],
"fproject": {
"note_id": "144149A40134720B472588D20024C110",
"CurrentOwner": "ทดสอบ~ทดสอบ~ทดสอบ",
"sql_id": "test",
"FormTitle": "test",
"ProjectName": ".net",
"StatusText": "test",
"StatusNo": "100",
"IDFac": "test",
"OwnerNamelist": "test",
"SYear": "test",
"Reason": "test",
"Result": "TEST",
"EPeriod": "",
"budgetyear": "",
"Goal": "test",
"ProjectStatus": "1",
"ApproveOwner": "ทดสอบ~ทดสอบ~ทดสอบ",
"budget2": 0,
"SPeriod": "",
"FaceName": "test",
"Updatedate_dt": "",
"ProjectDetail": "test",
"budget": 0,
"budgetApprove": 0
}
}
And this is my controller code
public static Root LoadDetailDataAPI()
{
Root ListData = new Root();
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://www.mywebsite.com/Develop/Project/Niems/EmitPlan.nsf/project.xsp/getprojectfull");
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))//, Encoding.UTF8
{
string json = new JavaScriptSerializer().Serialize(new
{
note_id = "144149A40134720B472588D20024C110"
});
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
ListData = Newtonsoft.Json.JsonConvert.DeserializeObject<Root>(result);
}
return ListData;
}
Factivityplan is returned as null. Fkpi and Fproject just binding note_id and sql_id. I do not have other fields. How can I fix it?

If you're already trying to map model to model using property names that match each other I would suggest looking into AutoMapper, that way you can simply map them directly without too much hassle like so:
mapper.Map<WantedDestinationType>(sourceModel);
If nothing else is configured, it'll simply map the types using the names only, if you have different naming, you can set it up in your mapping profile etc.

Related

Nested JSON data to datatable dynamically C#

{
"STATUS": "OK",
"projects": [
{
"startDate": "",
"last-changed-on": "2019-01-03T11:46:14Z",
"logo": "",
"created-on": "2018-12-12T10:04:47Z",
"privacyEnabled": false,
"status": "active",
"boardData": {},
"replyByEmailEnabled": true,
"harvest-timers-enabled": false,
"description": "",
"category": {
"color": "",
"id": "",
"name": ""
},
"id": "322852",
"overview-start-page": "default",
"start-page": "projectoverview",
"integrations": {
"xero": {
"basecurrency": "",
"countrycode": "",
"enabled": false,
"connected": "NO",
"organisation": ""
},
"sharepoint": {
"account": "",
"foldername": "root",
"enabled": false,
"folder": "root"
},
"microsoftConnectors": {
"enabled": false
},
"onedrivebusiness": {
"account": "",
"foldername": "root",
"enabled": false,
"folder": "root"
}
},
"defaults": {
"privacy": ""
},
"notifyeveryone": false,
"filesAutoNewVersion": false,
"defaultPrivacy": "open",
"tasks-start-page": "default",
"starred": false,
"announcementHTML": "",
"isProjectAdmin": true,
"name": "Project 2",
"company": {
"is-owner": "1",
"id": "78494",
"name": "MCG Company"
},
"endDate": "",
"announcement": "",
"show-announcement": false,
"subStatus": "current",
"tags": []
},
{
"startDate": "",
"last-changed-on": "2018-12-11T17:52:57Z",
"logo": "",
"created-on": "2018-11-26T11:11:00Z",
"privacyEnabled": false,
"status": "active",
"boardData": {},
"replyByEmailEnabled": true,
"harvest-timers-enabled": false,
"description": "",
"category": {
"color": "",
"id": "",
"name": ""
},
"id": "321041",
"overview-start-page": "default",
"portfolioBoards": [
{
"card": {
"id": "4771"
},
"board": {
"id": "544",
"name": "Project Implementations",
"color": "#F39C12"
},
"column": {
"id": "1573",
"name": "Go Live",
"color": "#F1C40F"
}
}
],
"start-page": "projectoverview",
"integrations": {
"xero": {
"basecurrency": "",
"countrycode": "",
"enabled": false,
"connected": "NO",
"organisation": ""
},
"sharepoint": {
"account": "",
"foldername": "root",
"enabled": false,
"folder": "root"
},
"microsoftConnectors": {
"enabled": false
},
"onedrivebusiness": {
"account": "",
"foldername": "root",
"enabled": false,
"folder": "root"
}
},
"defaults": {
"privacy": ""
},
"notifyeveryone": false,
"filesAutoNewVersion": false,
"defaultPrivacy": "open",
"tasks-start-page": "default",
"starred": false,
"announcementHTML": "",
"isProjectAdmin": true,
"name": "Project One",
"company": {
"is-owner": "1",
"id": "78494",
"name": "MCG Company"
},
"endDate": "",
"announcement": "",
"show-announcement": false,
"subStatus": "current",
"tags": []
}
]
}
This is the JSON response that I'm getting from an app, and there are a lot of other API gets that are returning the same kind of response (nested), so this has to be done dynamically as the user is adding API calls from a config file, so I cannot make pre-made classes with gets and sets.
My goal is to transform this data into a datatable to be inserted into a database
When I see a nested column, my goal is to have the parent column name attached to it with an "_" ex: category_id = ""
or integrations_xero_basecurrency = "", etc..
This is the code that I used to tabulate the data, but in the code it's only taking the column if it's a JValue (key and value), and I'm not able for the life of me to create a proper loop that will do the trick.
public DataTable Tabulate(string jsonContent)
{
var jsonLinq = JObject.Parse(jsonContent);
// Find the first array using Linq
var srcArray = jsonLinq.Descendants().Where(d => d is JArray).First();
//Console.WriteLine("extarcted data:" + srcArray);
var trgArray = new JArray();
foreach (JObject row in srcArray.Children<JObject>())
{
var cleanRow = new JObject();
foreach (JProperty column in row.Properties())
{
// Only include JValue types
if (column.Value is JValue)
{
cleanRow.Add(column.Name, column.Value);
}
}
trgArray.Add(cleanRow);
}
DataTable dt = JsonConvert.DeserializeObject<DataTable>(trgArray.ToString());
return dt;
}
How about something like this:
public DataTable Tabulate(string jsonContent)
{
var jsonLinq = JObject.Parse(jsonContent);
// Find the first array using Linq
var arrayProp = jsonLinq.Properties().First(p => p.Value is JArray);
var srcArray = (JArray)arrayProp.Value;
// Set up a regex consisting of the array property name and subscript
// (e.g. "projects[0]."), which we will strip off
var regex = new Regex($#"^{arrayProp.Name}\[\d+\]\.");
// Flatten each object of the original array
// into new objects and put them in a new array
var trgArray = new JArray(
srcArray.Children<JObject>()
.Select(row => new JObject(
row.Descendants()
.OfType<JProperty>()
.Where(p => p.Value is JValue)
.Select(p => new JProperty(
regex.Replace(p.Value.Path, "").Replace(".", "_"),
p.Value
))
))
);
// Convert the new array to a DataTable
DataTable dt = trgArray.ToObject<DataTable>();
return dt;
}
Working demo: https://dotnetfiddle.net/yrmcSQ

How to generate the Json format request using c# in VS?

Here is my method to generate the JSON formatter I'm using the SerializeObject json converter in code... But i'm stuck in adding the header value like shipper, destination & other headers here...
string json = #"{
'Shipper': {
}
}";
JObject rss = JObject.Parse(json);
JObject Shipper = (JObject)rss["Shipper"];
Shipper.Add("AddressId", ShipperAddressId);
Shipper.Add("ShipperReference", ShipperReference);
Shipper.Add("ShipperDepartment", ShipperDepartment);
Shipper.Add("CompanyName", ShipperCompanyName);
Shipper.Add("ContactName", ShipperContactName);
Shipper.Add("AddressLine1", ShipperAddressLine1);
Shipper.Add("AddressLine2", ShipperAddressLine2);
Shipper.Add("AddressLine3", ShipperAddressLine3);
Shipper.Add("Town", ShipperTown);
Shipper.Add("County", ShipperCounty);
Shipper.Add("CountryCode", ShipperCountryCode);
Shipper.Add("Postcode", ShipperPostcode);
Shipper.Add("PhoneNumber", ShipperPhoneNumber);
Shipper.Add("EmailAddress", ShipperEmailAddress);
Shipper.Add("VatNumber", ShipperVatNumber);
json = rss.ToString();
JObject jsonTxt = JObject.Parse(json);
string jsonreq = JsonConvert.SerializeObject(jsonTxt, Newtonsoft.Json.Formatting.Indented);
output I'm getting as :
{
"Shipper": {
"AddressId": "",
"ShipperReference": "Ref14",
"ShipperDepartment": "",
"CompanyName": "Intersoft Test Company",
"ContactName": "Intersoft ",
"AddressLine1": "Blays House",
"AddressLine2": "Englefield Green",
"AddressLine3": "Wick Road",
"Town": "Egham",
"County": "Surrey",
"CountryCode": "GB",
"Postcode": "TW20 0HJ",
"PhoneNumber": "7894561252",
"EmailAddress": "",
"VatNumber": ""
}
}
But my actual output should be like below format:
{
"Shipper":
{
"AddressId": "",
"ShipperReference": "",
"ShipperDepartment": "",
"CompanyName": "",
"ContactName": "Jane Smith",
"AddressLine1": "Level 5",
"AddressLine2": "Hashmoore House",
"AddressLine3": "10 Sky Lane",
"Town": "Leatherhead",
"County": "Surrey",
"CountryCode": "",
"Postcode": "",
"PhoneNumber": "07723456789",
"EmailAddress": "email#server.com",
"VatNumber": ""
},
"Destination":
{
"AddressId": "",
"CompanyName": "",
"ContactName": "",
"AddressLine1": "",
"AddressLine2": "10 Round Road",
"AddressLine3": "Mitre Peak",
"Town": "Leatherhead",
"County": "Surrey",
"CountryCode": "",
"Postcode": "",
"PhoneNumber": "",
"EmailAddress": "email#example.com",
"VatNumber": ""
},
"ShipmentInformation":
{
"ShipmentDate": "2020-03-04",
"ServiceCode": "",
"ServiceOptions": {
"PostingLocation": "",
"ServiceLevel": "01",
"ServiceFormat": "",
"Safeplace": "",
"SaturdayGuaranteed": false,
"ConsequentialLoss": "",
"LocalCollect": false,
"TrackingNotifications": "",
"RecordedSignedFor": ""
},
"TotalPackages": 1,
"TotalWeight": 0.75,
"WeightUnitOfMeasure": "KG",
"Product": "NDX",
"DescriptionOfGoods": "Clothing",
"ReasonForExport": "",
"Value": 100,
"Currency": "GBP",
"LabelFormat": "ZPL300DPI",
"SilentPrintProfile": "",
"ShipmentAction": "process",
"Packages":
[
{
"PackageOccurrence": 1,
"PackagingId": "",
"Weight": 0.75,
"Length": 15,
"Width": 15,
"Height": 15
}
],
"Items":
[
{
"ItemId": "",
"Quantity": 1,
"Description": "White Tee-shirt",
"Value": 100,
"Weight": 0.75,
"PackageOccurrence": 1,
"HsCode": "",
"SkuCode": "",
"CountryOfOrigin": "",
"ImageUrl": ""
}
]
}
}
But my issue is have to add the Destination , ShipmentInformation headers too....
I'm new to this json converter.... I hope you will be able to help me,
Thank you very much in Advance!
Copy your Expected Json into something like json2csharp as suggested. It will automatically generate the classes you need for serialization. That site is very helpful but you wanna make sure your Expected Json is in the finalized format.
Once it generates those classes, add those classes to your project.
Then you would need to populate your classes with data for instance base on your json and what i pasted into the site it created a RootObject with subclasses:
RootObject myJsonRoot = new RootObject();
myJsonRoot.Shipper = new Shipper(); //Or if you have a populated shipper class you can set it equal to that without having to fill the properties out one by one.
myJsonRoot.Shipper.AddressId = ShipperAddressId;
//Fill out Remaining Shipper Properties
myJsonRoot.Destination = new Destination();
myJsonRoot.Destination.AddressLine2 = ShipperAddressLine2;
//Fill out Remaining Destination and other classes Properties
//From here once your RootObject is fully populated you can call JsonConvert.Serialize
string output = JsonConvert.SerializeObject(myJsonRoot);
Now you have your expected Json in the output variable and do with it what you will.

What's the syntax to create an object that is an array of objects with JObject?

I'm creating a database seeder for Cosmos DB (a document or JSON based DB). Some of the C# models have a property Config that is JSON so I've been using this type of code to set that property:
Config = JObject.FromObject(new { })
which works as does actually setting property(ies) inside the object:
Config = JObject.FromObject(new
{
contextOptionSource = "$.domains.governmentEntityType_active"
}),
However, I can't figure out how to set Config to an array of objects. I tried actually using C# Models thinking that JObject would convert them for me like so:
Config = JObject.FromObject(
new List<Question>
{
new Question
{
Key = "contact",
Label = "Contact Person",
HelpText = "",
Config = JObject.FromObject(new {}),
Type = "text",
ContextTarget = "$.data.contact"
},
new Question
{
Key = "company",
Label = "Company Name",
HelpText = "",
Config = JObject.FromObject(new {}),
Type = "text",
ContextTarget = "$.data.company"
}
}),
This compiled OK but when I run I get a runtime error "Object serialized to Array. JObject instance expected.'" Am I wrong to think that JObject should convert the C# models to JSON? If they have to be generic objects that's fine but I can't get the syntax right that the FromObject method will accept multiple objects inside this Config property.
Edit: Here's the JSON I'm trying to produce:
"config": {
"questions": [{
"key": "contact",
"label": "Contact Person",
"helpText": "Contact Person",
"config": {},
"type": QuestionKind.Textbox,
"contextTarget": "$.data.contact",
"enabledRule": null,
"validationRules": [],
"visibleRule": null
},
{
"key": "company",
"label": "Company Name",
"helpText": "Company Name",
"config": {},
"type": QuestionKind.Textbox,
"contextTarget": "$.data.company",
"enabledRule": null,
"validationRules": [],
"visibleRule": null
}]
}
Try JToken or JArray.
var Config = JToken.FromObject(
new List<Question>
{
new Question
{
Key = "contact",
Label = "Contact Person",
HelpText = "",
Config = JObject.FromObject(new {}),
Type = "text",
ContextTarget = "$.data.contact"
},
new Question
{
Key = "company",
Label = "Company Name",
HelpText = "",
Config = JObject.FromObject(new {}),
Type = "text",
ContextTarget = "$.data.company"
}
}
);
var result = Config.ToString();
The result is:
[
{
"Label": "Contact Person",
"HelpText": "",
"Type": "text",
"ContextTarget": "$.data.contact",
"Config": {},
"Key": "contact"
},
{
"Label": "Company Name",
"HelpText": "",
"Type": "text",
"ContextTarget": "$.data.company",
"Config": {},
"Key": "company"
}
]
You need to know what type of JToken you want to create. For example, you can create a JObject either from a string value or from a .NET object. They are like factory methods. For example, if you want to create it from List<string>, you will have to tell the framework you will be creating a JArray from an in memory object:
var fromArray = JArray.FromObject(new List<string>
{
"One",
"Two"
});
Or that you will be creating JObject:
var fromObj = JObject.FromObject(new Customer() { Name = "Jon" });
Or you can create the tokens from JSON:
var fromJson = JArray.Parse("[\"One\", \"Two\"]");
Finally, you can just create JToken which is the parent of all the above classes (JArray, JObject) but then you will only have access to JToken properties and methods:
var Config = JToken.FromObject(
new List<string>
{
"One",
"Two"
});
See this for the various tokens.
so the C# code I needed to do so was:
Config = JObject.FromObject(new
{
questions = JArray.FromObject(
new List<Question>
{
new Question
{
Key = "contact",
Label = "Contact Person",
HelpText = "",
Config = emptyJObject,
Type = "text",
ContextTarget = "$.data.contact"
},
new Question
{
Key = "company",
Label = "Company Name",
HelpText = "",
Config = emptyJObject,
Type = "text",
ContextTarget = "$.data.company"
}
})
})
Use JArray, you can pick the constructor best suited for your needs here

Retrieve specific value from JSON in C#

I need to get values from the JSON below, for example how to index Id in Info?
The whole JSON consists of many matches, this just one with Id 5aa891cd1e1422452e8b4567, and this is a structure of one match.
I try with:
var jsonDATA = JObject.Parse(data);
foreach (var e in jsonDATA["events"]) {
//in this step, the result is JSON below
var id = e["info"]["id"];` // error: cannot access child value on newtonsoft json linq jproperty
}
Any ideas?
{"5aa891cd1e1422452e8b4567": {
"info": {
"id": "5aa891cd1e1422452e8b4567",
"event_id": "58911142245284567",
"name": "Santos Laguna vs Queretaro",
"sport": "Soccer",
"league": "Mexico Cup",
"period": "Finished",
"score": "1:0",
"status": "Live",
"start_time": "2018.03.14 03:06:53",
"state": 1017,
"state_name": "Fulltime",
"minute": 90,
"safe": false,
"safe2": false,
"blocked": false,
"stop": false
},
"stats": {
"home": {
"name": "Santos Laguna",
"color": "",
"position": "",
"on_target": "",
"off_target": "",
"attacks": "",
"dangerous_attacks": "",
"possession": "",
"goals": 1,
"corners": 5,
"yellowcards": 1,
"redcards": 0,
"throwins": 0,
"freekicks": 0,
"goalkicks": 0,
"penalties": 0,
"substitutions": 3,
"ht_result": 1
},
"away": {
"name": "Queretaro",
"color": "",
"position": "",
"on_target": "",
"off_target": "",
"attacks": "",
"dangerous_attacks": "",
"possession": "",
"goals": 0,
"corners": 8,
"yellowcards": 3,
"redcards": 1,
"throwins": 0,
"freekicks": 0,
"goalkicks": 0,
"penalties": 0,
"substitutions": 3,
"ht_result": 0
}
},
"odds": []
}}
You can use anonymous type deserialization for your data like this. Hope it works.
//using Newtonsoft.Json;
var jsonData = JsonConvert.DeserializeAnonymousType(
data,
new
{
events = new[]
{
new
{
Id = new { info = "", stats = "", away = "", odds = "" }
}
}
);
foreach(var item in jsonData.events)
{
var id=item.info.id; // getting id present in info
}

Issue With Reading Json Value

I have an application using the web api in c sharp. I have the following json, and i need to parse the
mobile_synch_tax_r
value to test for a condition. The issue is that while this method worked using a windows service, it is not working in the controller of the web api.
The relevant json is:
{"SYNC_DATA": {
"mobile_synch_tax_r": [
{
"idtax_registration":66,
"gender": "",
"title": "",
"name": "AK",
"home_address": "",
"state_of_origin": "A",
"home_town": "",
"local_government": "",
"occupation": "",
"company_name": "",
"office_address": "No",
"ministry": "",
"market": "",
"park": "",
"phone_number": "",
"email_address": "",
"photo_url": "",
"tax_id": "285",
"state": null,
"registered_by": "imported",
"biometric_status": 0,
"registration_type": 2,
"group_id": 100,
"taxpayer_password": "*6BB",
"tax_exempt": 0,
"active": 1,
"disability": "",
"rf1": 1,
"rf2": 1,
"rf3": 1,
"rf4": 1,
"rf5": 1,
"lf1": 1,
"lf2": 1,
"lf3": 1,
"lf4": 1,
"lf5": 1,
"registered_on": "2015",
"drivers_license_number": "",
"national_number": "",
"international_passport_number": "",
"company_rcc": "",
"workplace_category": "",
"office_lg": "",
"office_city": "n",
"parent_id": "",
"workplace_type": 0,
"marital_status": "",
"nationality": "u",
"vend_pin": 0,
"residential_address_status": "",
"dob": null,
"surname": "Ad",
"first_name": "",
"middle_name": "",
"utin": "",
"last_pw_reset_by": "",
"temp_reg": 0,
"company_size": "",
"business_commencement_date": null,
"proprietor_tax_id": "",
"business_ownership_type": "",
"has_subsidiary": false,
"subsidiary": false,
"subsidiary_of": "",
"n": "",
"locked": false,
"author": "",
"synch_status": false
}]}}
This is the code in the controller:
// POST api/ak
public HttpResponseMessage Post(HttpRequestMessage value)
{
var someText = value.Content.ReadAsStringAsync().Result;
Library.WriteErrorLog("Data Received" + someText);
var objects = JObject.Parse(someText);
Library.WriteErrorLog("Objects are" + objects);
if (objects != null)
{
foreach (KeyValuePair<String, JToken> app in objects)
{
var rootName = app.Key;
if (rootName == "mobile_synch_tax_r")
{"Have your way with me"}}
The code is not able to check if the
rootName=="mobile_synch_tax_r"
How am i missing it?
If you're just looking for value of the "mobile_synch_tax_r" property, you can use SelectToken to get it:
var mobile_synch_tax_r = objects.SelectToken("..mobile_synch_tax_r");
.. is the recursive descent operator, so this query searches the JSON object hierarchy for the first property named "mobile_synch_tax_r", and returns its value.

Categories

Resources