How to read a raw response and display as is as a string.
I am getting the response as below. How to extract the below response as string
{
"ProductDescription":
{
"ProductId": "1000222",
"ProducName": "iphone13Case"
},
"ProductDetails":{
"ProductDetails":
{
"ProductId": "1000222",
"ProducCode": "Apple13",
"ProducName": "iphone13Case",
"ProductColor": "Red",
"ProductModel": "iPhonePro"
}
}
}
public Class ProductDescription
{
public string ProductId;
Public string ProducName;
}
public Class ProductDetails
{
public string ProductId;
public string ProducCode;
Public string ProducName;
Public string ProductColor;
Public string ProductModel;
}
Public Class ProductOrderDetails
{
public ProductDetails prodDetails;
public ProductDescription prodDescription
}
ProductOrderDetails response = RestApiMethod(param1, param2);
I got the answer. I am using Newtonsoft. responseString will now contain the response as a string with indentation.
var responseString = JsonConvert.SerializeObject(response, Formatting.Indented);
Related
I want to return C# class object instead of using JObject in here. Could someone can tell me how to use it.
private async Task<JObject> GetReceiptById(string Id, string name)
{
var response = await _ApiService.Get(Id, name);
var responseStr = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
return JObject.Parse(responseStr);
}
throw new Exception(responseStr);
}
this method is return (return JObject.Parse(responseStr)); below JSON output. for that how to create a new class. I am not sure how to apply all in one class.
{
"receipts": [
{
"ReceiptHeader": {
"Company": "DHSC",
"ErpOrderNum": "730",
"DateTimeStamp": "2022-05-14T13:43:57.017"
},
"ReceiptDetail": [
{
"Line": 1.0,
"ITEM": "PP1016",
"ITEM_NET_PRICE": 0.0
},
{
"Line": 2.0,
"ITEM": "PP1016",
"ITEM_NET_PRICE": 0.0
}
],
"XrefItemsMapping": [],
"ReceiptContainer": [],
"ReceiptChildContainer": [],
"rPrefDO": {
"Active": null,
"AllowLocationOverride": null,
"DateTimeStamp": null
}
}
]
}
You can bind the Response Content to a known Type using ReadAsAsync<T>().
https://learn.microsoft.com/en-us/previous-versions/aspnet/hh835763(v=vs.118)
var result = await response.Content.ReadAsAsync<T>();
In your example you will also run into further issues as you are not closing your response after getting it from the Api Service Get method.
Below is a possible solution where you send your object type to the Get method. (not tested)
public virtual async Task<T> GetApiCall<T>(Id, name)
{
//create HttpClient to access the API
var httpClient = NewHttpClient();
//clear accept headers
httpClient.DefaultRequestHeaders.Accept.Clear();
//add accept json
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//return the client for use
using (var client = await httpClient )
{
//create the response
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
//create return object
try
{
var result = await response.Content.ReadAsAsync<T>();
//dispose of the response
response.Dispose();
return result;
}
catch
{
throw;
}
}
// do something here when the response fails for example
var error = await response.Content.ReadAsStringAsync();
//dispose of the response
response.Dispose();
throw new Exception(error);
}
}
What you probably looking for is Deserialization
you can achieve it with
var model = JsonConvert.Deserialize<YourClass>(responseStr);
return model;
but the class (YourClass) properties must match the json string you provided in responseStr.
As the comments section you asked for a generated class:
here is what should look like, after you generate the class.
Note: most of the times, you will need to edit the generated class.
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class Receipt
{
public ReceiptHeader ReceiptHeader { get; set; }
public List<ReceiptDetail> ReceiptDetail { get; set; }
public List<object> XrefItemsMapping { get; set; }
public List<object> ReceiptContainer { get; set; }
public List<object> ReceiptChildContainer { get; set; }
public RPrefDO rPrefDO { get; set; }
}
public class ReceiptDetail
{
public double Line { get; set; }
public string ITEM { get; set; }
public double ITEM_NET_PRICE { get; set; }
}
public class ReceiptHeader
{
public string Company { get; set; }
public string ErpOrderNum { get; set; }
public DateTime DateTimeStamp { get; set; }
}
public class Root
{
public List<Receipt> receipts { get; set; }
}
public class RPrefDO
{
public object Active { get; set; }
public object AllowLocationOverride { get; set; }
public object DateTimeStamp { get; set; }
}
generated by: https://json2csharp.com/
I want to be able to access the JSON objects with LINQ when the JSON is returned.
I have referred to Send JSON via POST in C# and Receive the JSON returned? and Send and receive json via HttpClient
This is what I have so far
public static async Task<string> GetMailTip(string user)
{
var jsonData = new StringContent(FormatJson(CreateJsonGettingMailTip(user)), Encoding.UTF8, "application/json");
var payload = await client.PostAsync($"https://graph.microsoft.com/v1.0/users/{user}/getMailTips", jsonData);
string responseContent = "";
if (payload.Content != null)
{
responseContent = await payload.Content.ReadAsStringAsync();
Console.WriteLine(responseContent);
}
var getMailTip = responseContent["value"]
.Children()
.Where(i => i != null)
.Select(c => c[""][""].Value<string>().Trim());
return responseContent;
}
The returned JSON is
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(microsoft.graph.mailTips)",
"value": [
{
"emailAddress": {
"name": "",
"address": ""
},
"automaticReplies": {
"message": "",
"messageLanguage": {
"locale": "",
"displayName": ""
},
"scheduledStartTime": {
"dateTime": "",
"timeZone": ""
},
"scheduledEndTime": {
"dateTime": "",
"timeZone": ""
}
}
}
]
}
I want to be able to access the message property in the JSON with LINQ
Any help would be appreciated
You go to http://quicktype.io (or similar online service, jsonutils, json2csharp, or use the Visual studio Paste Json as Classes feature - of all the sites that do this QT is the most full featured) to turn your json into classes. This makes it nicer to work with:
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using SomeNamespaceHere;
//
// var rootClassNameHere = RootClassNameHere.FromJson(jsonString);
namespace SomeNamespaceHere
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class RootClassNameHere
{
[JsonProperty("#odata.context")]
public Uri OdataContext { get; set; }
[JsonProperty("value")]
public Value[] Value { get; set; }
}
public partial class Value
{
[JsonProperty("emailAddress")]
public EmailAddress EmailAddress { get; set; }
[JsonProperty("automaticReplies")]
public AutomaticReplies AutomaticReplies { get; set; }
}
public partial class AutomaticReplies
{
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("messageLanguage")]
public MessageLanguage MessageLanguage { get; set; }
[JsonProperty("scheduledStartTime")]
public ScheduledTime ScheduledStartTime { get; set; }
[JsonProperty("scheduledEndTime")]
public ScheduledTime ScheduledEndTime { get; set; }
}
public partial class MessageLanguage
{
[JsonProperty("locale")]
public string Locale { get; set; }
[JsonProperty("displayName")]
public string DisplayName { get; set; }
}
public partial class ScheduledTime
{
[JsonProperty("dateTime")]
public string DateTime { get; set; }
[JsonProperty("timeZone")]
public string TimeZone { get; set; }
}
public partial class EmailAddress
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("address")]
public string Address { get; set; }
}
public partial class RootClassNameHere
{
public static RootClassNameHere FromJson(string json) => JsonConvert.DeserializeObject<RootClassNameHere>(json, SomeNamespaceHere.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this RootClassNameHere self) => JsonConvert.SerializeObject(self, SomeNamespaceHere.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}
(I chose "SomeNamespaceHere" and "RootClassNameHere" for the relevant names of namespace and class root; you might choose different)
And then you use it like this (the deser step will work differently depending on the service you used):
var rootClassNameHere = RootClassNameHere.FromJson(jsonString); //deser
var someLinq = rootClassNameHere.Value.Select(v => v.AutomaticReplies.Message); //query
I'm writing a Controller Action to accept a Post request from a webhook in Azure EventGrid. The examples in the documentation manually parse the json from the HTTP request into a Microsoft.Azure.EventGrid.Models.EventGridEvent object.
https://learn.microsoft.com/en-us/azure/event-grid/receive-events
This seemed a little complicated to me and I thought that I should have been able to let .Net deseralize the Json for me. My understanding that .Net should deserialize a JSON object into the expected object of the action.
My Action is as follows.
[HttpPost]
public async Task<OkObjectResult> Post(EventGridEvent gridEvent)
{
var response = string.Empty;
if (gridEvent.EventType == EventTypes.EventGridSubscriptionValidationEvent)
{
// Validate
var eventData = (SubscriptionValidationEventData) gridEvent.Data;
var responseData = new SubscriptionValidationResponse()
{
ValidationResponse = eventData.ValidationCode
};
return new OkObjectResult(responseData);
}
if (gridEvent.EventType == EventTypes.StorageBlobCreatedEvent)
{
var eventData = (StorageBlobCreatedEventData) gridEvent.Data;
// Get File
// Validate File
// Dispatch Events
}
return new OkObjectResult(response);
}
I'm sending a Post request to the Action via postman and using a sample body from the docs
[{
"topic": "/subscriptions/{subscription-id}/resourceGroups/Storage/providers/Microsoft.Storage/storageAccounts/xstoretestaccount",
"subject": "/blobServices/default/containers/testcontainer/blobs/testfile.txt",
"eventType": "Microsoft.Storage.BlobCreated",
"eventTime": "2017-06-26T18:41:00.9584103Z",
"id": "831e1650-001e-001b-66ab-eeb76e069631",
"data": {
"api": "PutBlockList",
"clientRequestId": "6d79dbfb-0e37-4fc4-981f-442c9ca65760",
"requestId": "831e1650-001e-001b-66ab-eeb76e000000",
"eTag": "0x8D4BCC2E4835CD0",
"contentType": "text/plain",
"contentLength": 524288,
"blobType": "BlockBlob",
"url": "https://example.blob.core.windows.net/testcontainer/testfile.txt",
"sequencer": "00000000000004420000000000028963",
"storageDiagnostics": {
"batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0"
}
},
"dataVersion": "",
"metadataVersion": "1"
}]
I checked what the EventGridEvent object looks like and everything looks correct and the json mapps to the expected object
public class EventGridEvent
{
public EventGridEvent()
{
}
public EventGridEvent(
string id,
string subject,
object data,
string eventType,
DateTime eventTime,
string dataVersion,
string topic = null,
string metadataVersion = null)
{
...
}
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "topic")]
public string Topic { get; set; }
[JsonProperty(PropertyName = "subject")]
public string Subject { get; set; }
[JsonProperty(PropertyName = "data")]
public object Data { get; set; }
[JsonProperty(PropertyName = "eventType")]
public string EventType { get; set; }
[JsonProperty(PropertyName = "eventTime")]
public DateTime EventTime { get; set; }
[JsonProperty(PropertyName = "metadataVersion")]
public string MetadataVersion { get; private set; }
[JsonProperty(PropertyName = "dataVersion")]
public string DataVersion { get; set; }
public virtual void Validate()
{
...
}
}
The only property that deserializes for me is eventTime and everything else is null
this ended up being a simple issue. I had forgotten to add [FromBody] before the expected type.
so My controller action became
[HttpPost]
public async Task<OkObjectResult> Post([FromBody]List<EventGridEvent> request)
{
...
}
using System;
using SQLite;
namespace Students
{
public class Student
{
public Student()
{
}
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string Name { get; set; }
public string percent { get; set; }
public string rollNo { get; set; }
}
}
This is my SQLite database class that i use to instantiate objects of type Students. What i want now is really simple, A simple hardcoded JSON object declared in C# ,Serialized ,which i can store to this database after deserialising it(Just to test and see if it's working)
My sample JSON which im trying to get stored in the database is :
[
{
"name": "Gopi",
"rollNo": "13",
"%age": "33"
},
{
"name": "Topi",
"rollNo": "23",
"%age": "43"
},
{
"name": "Kopi",
"rollNo": "33",
"%age": "53"
}
]
I want to store these values into my SQLite database after parsing this JSON object in C#. Im not sure how to proceed.
Create some handling class like:
public class Handler{
public string name { get; set; }
public string rollNo { get; set; }
public string age { get; set; }}
And then:
public static HttpClient CreateClient()
{
var httpClient = new HttpClient
{
BaseAddress = new Uri(someURL)
};
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return httpClient;
}
public static async Task<string> Get(string path)
{
using (var client = CreateClient())
{
var getResponse = await client.GetAsync(path);
return await getResponse.Content.ReadAsStringAsync();
}
}
public async Task<string> UpdateFriendsLocation()
{
var response = await WebServices.Get(someURL);
return response;
}
//In the place you want
var resp = JsonConvert.DeserializeObject<Handler>(response);
With this in your handler you have the data and then you have to make the inputs in your SQLite from that data.
"responseCode": String
"responseMessage": String
"responseBody": { "conversations": [
{
"conversationId": String,
"state": String,
"conversationType": String,
"mediaType": Enum,
"startDate":Integer,
"duration": Integer,
"tags":[{ "tagName":String,
"tagType":String,
"tagCreateDate":Integer,
"tagOffset":Integer
}],
]}
This schema continues, but my question regarding the first section applies to the rest...
How can I deserialize a JSON response based on this schema into .NET objects? what would the .NET object look like?
Is there another way to read it ? (like a .NET Dataset type of way?)
Thanks. Roey.
If you want (or have to) to use JavaScriptSerializer the code could look like following:
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
namespace JsonSer {
public class MyTag {
public string tagName { get; set; }
public string tagType { get; set; }
public long tagCreateDate { get; set; }
public int tagOffset { get; set; }
}
public enum MyMedia {
Diskette,
UsbStick,
Disk,
Internet
}
public class MyConversation {
public string conversationId { get; set; }
public string state { get; set; }
public string conversationType { get; set; }
public MyMedia mediaType { get; set; }
public long startDate { get; set; }
public int duration { get; set; }
public List<MyTag> tags { get; set; }
}
public class MyConversations {
public List<MyConversation> conversations { get; set; }
}
public class MyData {
public string responseCode { get; set; }
public string responseMessage { get; set; }
public MyConversations responseBody { get; set; }
}
class Program {
static void Main (string[] args) {
MyData data = new MyData () {
responseCode = "200",
responseMessage = "OK",
responseBody = new MyConversations () {
conversations = new List<MyConversation> () {
new MyConversation() {
conversationId = "conversation1",
state = "state1",
conversationType = "per JSON",
mediaType = MyMedia.Internet,
startDate = DateTime.Now.Ticks,
duration = 12345,
tags = new List<MyTag>() {
new MyTag() {
tagName = "tagName1",
tagType = "tagType1",
tagCreateDate = DateTime.Now.Ticks,
tagOffset = 1
}
}
}
}
}
};
Console.WriteLine ("The original data has responseCode={0}", data.responseMessage);
JavaScriptSerializer serializer = new JavaScriptSerializer ();
string json = serializer.Serialize (data);
Console.WriteLine ("Data serialized with respect of JavaScriptSerializer:");
Console.WriteLine (json);
MyData d = (MyData)serializer.Deserialize<MyData> (json);
Console.WriteLine ("After deserialization responseCode={0}", d.responseMessage);
}
}
}
the corresponding JSON data will be look like
{
"responseCode": "200",
"responseMessage": "OK",
"responseBody": {
"conversations": [
{
"conversationId": "conversation1",
"state": "state1",
"conversationType": "per JSON",
"mediaType": 3,
"startDate": 634207605160873419,
"duration": 12345,
"tags": [
{
"tagName": "tagName1",
"tagType": "tagType1",
"tagCreateDate": 634207605160883420,
"tagOffset": 1
}
]
}
]
}
}
You can easy modify the code if you decide to use DataContractJsonSerializer.
First you can beautify all your JSON using http://jsbeautifier.org/ to make it more readable, and then the only way I know is to just go through every property step by step and create classes for them. You should add the [DataContract] attribute for classes and the [DataMember] attribute for properties.
Example
[DataContract]
public class Response{
[DataMember]
public string responseCode {get;set;}
[DataMember]
public string responseMessage {get;set;}
[DataMember]
public ResponseBody responseBody {get;set;}
}
Automatic generation of these classes
There are alternatives for XMLSerialization (using XSD) but as far as I know there are no similar solutions for json thus far.
To finally deserialize the json into .NET object you can use the following code:
Response myResponse = new Person();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(myResponse.GetType());
myResponse = serializer.ReadObject(ms) as Response;
ms.Close();
Where Response would be the type of object that represents the root of your json.
For more information visit the MSDN page of the DataContractJsonSerializer class.