how can I get json data in to the c# object? - c#

Below is my class for the json output:
class PwdResetRequest
{
public class TopScoringIntent
{
public string intent { get; set; }
public double score { get; set; }
}
public class Intent
{
public string intent { get; set; }
public double score { get; set; }
}
public class Resolution
{
public string value { get; set; }
}
public class Entity
{
public string entity { get; set; }
public string type { get; set; }
public int startIndex { get; set; }
public int endIndex { get; set; }
public Resolution resolution { get; set; }
}
public class RootObject
{
public string query { get; set; }
public TopScoringIntent topScoringIntent { get; set; }
public List<Intent> intents { get; set; }
public List<Entity> entities { get; set; }
}
}
Luis Return result:
{
"query": "create a new password for sjao9841#demo.com",
"topScoringIntent": {
"intent": "ResetLANIDpassword",
"score": 0.9956063
},
"intents": [
{
"intent": "ResetLANIDpassword",
"score": 0.9956063
},
{
"intent": "None",
"score": 0.179328963
}
],
"entities": [
{
"entity": "sjao9841#demo.com",
"type": "builtin.email",
"startIndex": 26,
"endIndex": 47
}
]
}
I have developed the below code for getting the data from the json.
var uri =
"https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/" +
luisAppId + "?" + queryString;
var response = await client.GetAsync(uri);
var strResponseContent = await response.Content.ReadAsStringAsync();
var json = await response.Content.ReadAsStringAsync();
var token = JObject.Parse(json).SelectToken("entities");
foreach (var item in token)
{
var request = item.ToObject<Entity>();
}
// Display the JSON result from LUIS
Console.WriteLine(strResponseContent.ToString());
}
And I only want the data from the "TopScoringIntent". How can I get that using C#? Below is the code that I tried but nothing came out:
Message=Error reading JObject from JsonReader. Path '', line 0, position 0.
Source=Newtonsoft.Json

I may be missing your intent, but if you only care about specific value rather than the entire javascript object, you could do the following.
dynamic json = JsonConvert.Deserialize(data);
var score = json.TopScoringIntent.Score;
That provides the specific value of score within TopScoringIntent. Obviously, you could also build a collection also well, by modifying slightly.
foreach(var point in json.Intents)
Console.WriteLine($"{point[1]} or {point.score}");
I believe that is what you're looking for, to receive a specific value from your object. Please note dynamics are useful, but this approach is a fairly quick and dirty, may not be ideal for your implementation.

quicktype generated the following C# classes and JSON.Net marshaling code for your sample data:
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var pwdResetRequest = PwdResetRequest.FromJson(jsonString);
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Net;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using J = Newtonsoft.Json.JsonPropertyAttribute;
public partial class PwdResetRequest
{
[J("query")] public string Query { get; set; }
[J("topScoringIntent")] public Ntent TopScoringIntent { get; set; }
[J("intents")] public Ntent[] Intents { get; set; }
[J("entities")] public Entity[] Entities { get; set; }
}
public partial class Entity
{
[J("entity")] public string EntityEntity { get; set; }
[J("type")] public string Type { get; set; }
[J("startIndex")] public long StartIndex { get; set; }
[J("endIndex")] public long EndIndex { get; set; }
}
public partial class Ntent
{
[J("intent")] public string Intent { get; set; }
[J("score")] public double Score { get; set; }
}
public partial class PwdResetRequest
{
public static PwdResetRequest FromJson(string json) => JsonConvert.DeserializeObject<PwdResetRequest>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this PwdResetRequest self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters = {
new IsoDateTimeConverter()
{
DateTimeStyles = DateTimeStyles.AssumeUniversal,
},
},
};
}
}
Now you can use System.Linq to get the maximum Ntent by Score:
var uri = $"https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/${luisAppId}?${queryString}";
var response = await client.GetAsync(uri);
var json = await response.Content.ReadAsStringAsync();
var request = PwdResetRequest.FromJson(json);
var maxIntent = request.Intents.MaxBy(intent => intent.Score);
Here's the generated code in a playground so you can change the type names and other options.

Related

convert API response to class object in C# by removing data type from response

I am getting API response something like this
{
"results": [{
"itemdescription": {
"raw": "xyz"
},
"productcategory5": {
"raw": "avx"
},
"productcategory6": {
"raw": "DG"
}
}]
}
I am trying to convert this to class object using DeserializeObject
lObjJsonData = JsonConvert.DeserializeObject<ProductVm>(lObjResponseData);
but in my VM I have to add extra property
[JsonProperty("raw")]
public string raw { get; set; }
How I can avoid this as if I convert my class object to json it will again have datatype property with every field .
my class code is below -
public class ProductAppSearchVm
{
public MetaClass meta { get; set; }
public List<ProductDetails> results { get; set; }
}
public class ProductProperty
{
[JsonProperty("raw")]
public string raw { get; set; }
}
public class ProductDetails
{
public ProductProperty itemdescription{ get; set; }
public ProductProperty productcategory5{ get; set; }
public ProductProperty productcategory6{ get; set; }
}
any suggestion how can I have simple data like -
{
"results": [{
"itemdescription": "xyz"
},
{
"productcategory5": "avx"
},
{
"productcategory6": "DG"
}
]
}
**Not yet sure performance wise. But for your desired output this might give you a hint.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string jsonString = "{\"results\":[{\"itemdescription\":{\"raw\":\"xyz\"},\"productcategory5\":{\"raw\":\"avx\"},\"productcategory6\":{\"raw\":\"DG\"}}]}";
var obj = JsonConvert.DeserializeObject<ProductDetails>(jsonString);
Console.WriteLine(obj.GetFormattedJson);
Console.ReadKey();
}
}
public class ProductDetails
{
[JsonProperty("results")]
public List<Dictionary<string, ProductProperty>> Detail { get; set; }
public string GetFormattedJson
{
get
{
return string.Join(",", Detail.Select(dic => "{\"results\":[" + string.Join(",", dic.Select(pp => $"{{\"{pp.Key}\":\"{pp.Value.Raw}\"}}")) + "]}"));
}
}
}
public class ProductProperty
{
[JsonProperty("raw")]
public string Raw { get; set; }
}
}
Output:

How to parse the JSON and get the data row by row?

I would like to ask how do I get the data using the JSON. I am using the Web API and deploy using request and response.
Class1.cs
This is calling the web API by using the request and response.
public static string Test()
{
string strReq = "{ \"header\": { \"Token\": \"ba42d11f - e0ae - 4d6c - 800a - 1564485b7ccb\"},\"body\": { \"SOHeaders\": [{ \"WarehouseCode\": \"W001\", \"CompanyCode\": \"C001\", \"SONo\": \"SO001\"}]}}";
UploadToBCSSoftSCM a = new UploadToBCSSoftSCM();
string strRes = a.GetSOSts(strReq);
return strRes;
}
HomeController.cs
I can get the response from here but I don't know how to split or parse the data.
public ActionResult Index()
{
// ViewBag.Title = "Home Page";
string r = Class1.Test();
Debug.WriteLine(r);
return View();
}
The result of response is
{
"header": {
"Token": "7c6cbeba-ff57-40d2-8759-84ccb59235fd",
"DtTime": "2020-02-20 13:10:34.365",
"ResultCode": "S",
"ResultMsg": ""
},
"body": [
{
"WarehouseCode": "W001",
"CompanyCode": "C001",
"SONo": "SO001",
"SOSts": "New"
}
]
}
O site json2csharp.com you can generate classes necessary to deserialize JSON.
public class Header
{
public string Token { get; set; }
public string DtTime { get; set; }
public string ResultCode { get; set; }
public string ResultMsg { get; set; }
}
public class Body
{
public string WarehouseCode { get; set; }
public string CompanyCode { get; set; }
public string SONo { get; set; }
public string SOSts { get; set; }
}
public class RootObject
{
public Header header { get; set; }
public List<Body> body { get; set; }
}
Then using JSON.NET you can deserialize your response into objects.
var data = JsonConvert.DeserializeObject<RootObject>(json);
and then in loop you can reach all records
foreach(var d in data.body)
{
}

Map JSON object to C# class property array

JSON
{
"SoftHoldIDs": 444,
"AppliedUsages": [
{
"SoftHoldID": 444,
"UsageYearID": 223232,
"DaysApplied": 0,
"PointsApplied": 1
}
],
"Guests": [
1,
2
]
}
In the above JSON SoftholdIDs is integer and AppliedUsages is class array property in C# Model
Issue is --How we can map JSON to class property.
Class code
public class ReservationDraftRequestDto
{
public int SoftHoldIDs { get; set; }
public int[] Guests { get; set; }
public AppliedUsage[] AppliedUsages { get; set; }
}
public class AppliedUsage
{
public int SoftHoldID { get; set; }
public int UsageYearID { get; set; }
public int DaysApplied { get; set; }
public int PointsApplied { get; set; }
}
Tried below code for mapping
ReservationDraftRequestDto reservationDto = null;
dynamic data = await reservationDraftRequestDto.Content.ReadAsAsync<object>();
reservationDto = JsonConvert.DeserializeObject<ReservationDraftRequestDto>(data.ToString());
You need to change
dynamic data = await reservationDraftRequestDto.Content.ReadAsAsync<object>();
to
string data = await reservationDraftRequestDto.Content.ReadAsStringAsync();
this will read your response as string
then do
reservationDto = JsonConvert.DeserializeObject<ReservationDraftRequestDto>(data);
this work
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
string json = #"{""SoftHoldIDs"": 444,""AppliedUsages"": [ {""SoftHoldID"": 444,""UsageYearID"": 223232,""DaysApplied"": 0,""PointsApplied"": 1}],""Guests"": [ 1, 2]}";
Rootobject reservationDto = JsonConvert.DeserializeObject<Rootobject>(json.ToString());
Debug.WriteLine(reservationDto.SoftHoldIDs);
foreach (var guest in reservationDto.Guests)
{
Debug.WriteLine(guest);
}
}
}
public class Rootobject
{
public int SoftHoldIDs { get; set; }
public Appliedusage[] AppliedUsages { get; set; }
public int[] Guests { get; set; }
}
public class Appliedusage
{
public int SoftHoldID { get; set; }
public int UsageYearID { get; set; }
public int DaysApplied { get; set; }
public int PointsApplied { get; set; }
}
}
First create class copying json as classwith visualstudio.
Next you have double quote in json respons so deal with it.
Json.NET: Deserilization with Double Quotes

how to get data from json in c#?

I Get json data from third party in json format.
I am trying to fetch RollId from "Id" and MType from "Data" in some cases
"Data" doesn't have fields it is kind of blank.
It's working when we have "Data". In case of blank it's not working.
any idea on this? Is there a better approach of doing this?
This is the Json
string json = #"{
'root': {
'_type': '_container',
'Class': '.key.PModel',
'Elements': {
'_type': 'array<element>',
'_data': [
{
'_type': 'element',
'Class': '.key.PElement',
'Id': {
'_type': 'testId',
'Class': '.key.PModel',
'RollId': '.key.7157'
},
'Data': {
'_type': 'p_model',
'Class': '.key.Unsupported',
'MType': '.TestMType',
'Version': {
'_type': 'test__version',
'Class': '.key.TestVersion',
}
}
},
{
'_type': 'element',
'Class': '.key.PElement',
'Id': {
'_type': 'TestId',
'Class': '.key.PModel',
'RollId': '.key.11261'
},
'Data': '.ref.root.Elements.0.Data'
},
{
'_type': 'element',
'Class': '.key.PElement',
'Id': {
'_type': 'TestId',
'Class': '.key.PModel',
'RollId': '.key.7914'
},
'Data': '.ref.root.Elements.0.Data'
}
]
}
}
}";
This is the Code
public class Program
{
static void Main(string[] args)
{
//it provide json
var testCont = thirdpartyapi();
var dataList = new List<TestResponse>();
foreach (var testData in testCont.Elements())
{
var data = new TestResponse();
data.col1 = Convert.ToInt32(testData.Id().RollId());
data.col2 = testData.Data().MType().ToString();
dataList.Add(data);
}
}
public class TestResponse
{
public int col1 { get; set; }
public string col2 { get; set; }
}
}
First, try to get a valid well-formed json. You can use this code beautify tool. Then you can automatically generate C# class using json2csharp. Finally as you have C# class you can apply if statements and check if property is null.
Generated C# wrapper:
public class Id
{
public string _type { get; set; }
public string Class { get; set; }
public string RollId { get; set; }
}
public class Datum
{
public string _type { get; set; }
public string Class { get; set; }
public Id Id { get; set; }
public object Data { get; set; }
}
public class Elements
{
public string _type { get; set; }
public List<Datum> _data { get; set; }
}
public class Root
{
public string _type { get; set; }
public string Class { get; set; }
public Elements Elements { get; set; }
}
public class RootObject
{
public int encoding_version { get; set; }
public Root root { get; set; }
}
If you want to pick only few fields from complex JSON, you can consider using Cinchoo ETL - an open source library
Sample below shows how to pick RollId and MType values from your json
using (var r = new ChoJSONReader("## YOUR JSON FILE PATH ##")
.WithJSONPath("$.._data")
.WithField("RollId", jsonPath: "$..Id.RollId", fieldType: typeof(string))
.WithField("MType", jsonPath: "$..Data.MType", fieldType: typeof(string))
)
{
foreach (var rec in r)
{
Console.WriteLine((string)rec.RollId);
Console.WriteLine((string)rec.MType);
}
}
Hope it helps.
The easiest way is use the DataContractJsonSerializer
Here you can read more about it.
All in all you need to create a model which has the same possible outcome as your json.
Then you can just use the DataContractJsonSerializer to create an object of you model by using a MemoryStream.
Here you can find a nice tool to create the model from the JSON.
For example this one:
public class Id
{
public string _type { get; set; }
public string Class { get; set; }
public string RollId { get; set; }
}
public class Datum
{
public string _type { get; set; }
public string Class { get; set; }
public Id Id { get; set; }
public object Data { get; set; }
}
public class Elements
{
public string _type { get; set; }
public List<Datum> _data { get; set; }
}
public class Root
{
public string _type { get; set; }
public string Class { get; set; }
public Elements Elements { get; set; }
}
public class RootObject
{
public int encoding_version { get; set; }
public Root root { get; set; }
}
Then you use the MemoryStream and the DataContractJsonSerializer to Create an object of RootObject from that JSON.
MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(RootObject));
stream1.Position = 0;
RootObject rootObject = (RootObject)ser.ReadObject(stream1);
And yes, as Adriani6 mentiones - your JSON is invalid at this point:
"Data": {
"_type": "p_model",
"Class": ".key.Unsupported",
"MType": ".TestMType",
"Version": {
"_type": "test__version",
"Class": ".key.TestVersion",
}
There is a , at the end wich is not allowed.

Invalid class property declaration for json mapping

I have below json received from mailgun API.
{
"items": [{
"delivery-status": {
"message": null,
"code": 605,
"description": "Not delivering to previously bounced address",
"session-seconds": 0
},
"event": "failed",
"log-level": "error",
"recipient": "test#test.com"
},
{
//some other properties of above types
}]
}
Now I was trying to create a class structure for above json to auto-map the properties after deserializing.
public class test
{
public List<Item> items { get; set; }
}
public class Item
{
public string recipient { get; set; }
public string #event { get; set; }
public DeliveryStatus delivery_status { get; set; }
}
public class DeliveryStatus
{
public string description { get; set; }
}
This is how I deserialize and try to map the properties.
var resp = client.Execute(request);
var json = new JavaScriptSerializer();
var content = json.Deserialize<Dictionary<string, object>>(resp.Content);
test testContent = (test)json.Deserialize(resp.Content, typeof(test));
var eventType = testContent.items[0].#event;
var desc = testContent.items[0].delivery_status.description; //stays null
Now in the above class Item, recipient and #event gets mapped properly and since it was a keyword I was suppose to use preceding # character and it works well. But the delivery-status property from json, does not get mapped with delevery_status property in class DeliveryStatus. I have tried creating it as deliveryStatus or #deliver-status. The earlier on doesn't map again and the later one throws compile time exception. Is there anyway these things can be handled, like declaring a property with - in between? I cannot change response json as it is not getting generated from my end. Hoping for some help.
Update
Changed the class as below referring this answer, but did not help. Its null again.
public class Item
{
public string #event { get; set; }
[JsonProperty(PropertyName = "delivery-status")]
public DeliveryStatus deliveryStatus { get; set; }
}
I am not sure what the issue is at your end, but at least it works if you use this code. Make sure to include a recent version of Newtonsoft.Json in your project and you should be fine.
public class DeliveryStatus
{
public object message { get; set; }
public int code { get; set; }
public string description { get; set; }
[JsonProperty("session-seconds")]
public int session_seconds { get; set; }
}
public class Item
{
[JsonProperty("delivery-status")]
public DeliveryStatus delivery_status { get; set; }
public string #event { get; set; }
[JsonProperty("log-level")]
public string log_level { get; set; }
public string recipient { get; set; }
}
public class RootObject
{
public List<Item> items { get; set; }
}
public static void Main(string[] args)
{
string json = #"{
""items"": [{
""delivery-status"": {
""message"": null,
""code"": 605,
""description"": ""Not delivering to previously bounced address"",
""session-seconds"": 0
},
""event"": ""failed"",
""log-level"": ""error"",
""recipient"": ""test#test.com""
}]
}";
RootObject r = JsonConvert.DeserializeObject<RootObject>(json);
}

Categories

Resources