How to deserialize Nested json of wcf service to object - json

I've created a Web Service to receive data from Android json.
The json i receive is:
{
"assignmentId":"5476",
"newProductName":"ALGOBOX NET USB",
"Attributes": {
"Ammyy": "fvhbhgfc",
"Database": "h j j i i ",
"Plan": "555555555"
}
}
I want to deserialize the json and although i managed to deserialize the root elements, cannot deserialize the Nested:
"Attributes": {
"Ammyy": "fvhbhgfc",
"Database": "h j j i i ",
"Plan": "555555555"
}
The problem is that the attributes must be dynamic (Ammmy, Database, etc), so i cannot create a class with these strings. I want to deserialize the nested object to a Dictionary or KeyValuePair.
The classes that i've created are these:
public class RequestDataNewProduct
{
public string assignmentId { get; set; }
public string newProductName { get; set; }
public List<Atts> Attributes { get; set; }
}
public class Atts
{
public List<KeyValuePair<string, string>> Attributes { get; set; }
}
Any help?

the C# typed equivalent for your json should look like -
public class Attributes
{
public string Ammyy { get; set; }
public string Database { get; set; }
public string Plan { get; set; }
}
public class RequestDataNewProduct
{
public string assignmentId { get; set; }
public string newProductName { get; set; }
public Attributes Attributes { get; set; }
}
Then just deserialize it -
var t = JsonConvert.DeserializeObject<RequestDataNewProduct>(json); //success
Console.WriteLine(t.Attributes.Ammyy); //fvhbhgfc

Related

Error deserializing json with nested arrays

I'm trying to deserialize a json object that includes nested arrays and I get the following error when I try it in Postman:
{
"errors": {
"accounts": [
"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Orders.Dtos.Accounts' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.\r\nPath 'accounts', line 7, position 17."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-92466567188264cbdc71e6f6d7479688-fe08150cd947ddf1-00"
}
Simplified json to deserialize:
{
"plannedShippingDateAndTime": "2023-02-07T07:06:00 GMT+01:00",
"pickup": {
"isRequested": false
},
"productCode": "N",
"accounts": [
{
"typeCode": "shipper",
"number": "999999999"
}
]
}
Classes:
public class ShipmentData
{
public string PlannedShippingDateAndTime { get; set; }
public Pickup Pickup { get; set; }
public string ProductCode { get; set; } = "N";
public Accounts Accounts { get; set; }
}
public class Pickup
{
public bool isRequested { get; set; }
}
public class Accounts
{
public ArrayAccounts[] ArrayAccounts { get; set; }
}
public class ArrayAccounts
{
public string TypeCode { get; set; }
public string Number { get; set; }
}
Api Controller:
[HttpPost("CreateShipment/{OrderId}")]
public async Task<ActionResult> CreateShipment(string OrderId, ShipMentData shipmentData)
{
...
}
public class ShipmentData
{
public string PlannedShippingDateAndTime { get; set; }
public Pickup Pickup { get; set; }
public string ProductCode { get; set; }
public Account[] Accounts { get; set; }
}
public class Pickup
{
public bool IsRequested { get; set; }
}
public class Account
{
public string TypeCode { get; set; }
public string Number { get; set; }
}
Also Customize JSON binding:
options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;

Deserialize JSON string embedded within JSON directly

I'm using .netcore 3.1 and I'm using System.Text.Json for serialization and deserialization. I didn't know how to phrase my question precisely. I looked around but couldn't find a direct answer for my question.
Apologies if it's a duplicate.
This is a sample JSON response.
{
"properties": {
"subscriptionId": "sub1",
"usageStartTime": "2015-03-03T00:00:00+00:00",
"usageEndTime": "2015-03-04T00:00:00+00:00",
"instanceData": "{\"Microsoft.Resources\":{\"resourceUri\":\"resourceUri1\",\"location\":\"Alaska\",\"tags\":null,\"additionalInfo\":null}}",
"quantity": 2.4000000000,
"meterId": "meterID1"
}
}
I'm interested in directly parsing instanceData.
If you observe closely, instanceData is an embedded JSON string.
{
"Microsoft.Resources": {
"resourceUri": "resourceUri1",
"location": "Alaska",
"tags": null,
"additionalInfo": null
}
}
Question:
Is it possible to parse this instanceData while the whole Json is being parsed? Can we add some Attributes to instanceData field for direct parsing? Right now, I'm accessing the string from the parsed model class and parsing instanceData separately.
This is what I'm doing right now (something like this):
JsonSerializer.Deserialize<MicrosoftResources>(parsedResponse.instanceData).
I have already built model classes for instanceData and other entities. Currently, instanceData is of type string in my root model class.
I'm interested in directly parsing instanceData. If you observe closely, instanceData is an embedded JSON string
Is it possible to parse this instanceData while the whole Json is being parsed?
You can achieve above requirement by creating and using a custom converter, like below.
public class ResConverter : JsonConverter<InstanceData>
{
public override InstanceData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
//you can implement it based on your actual requirement
//...
string jsonData = reader.GetString();
var instanceData = System.Text.Json.JsonSerializer.Deserialize<InstanceData>(jsonData);
return instanceData;
}
Model Classes
public class MyModel
{
public Properties Properties { get; set; }
}
public class Properties
{
public string SubscriptionId { get; set; }
public DateTimeOffset UsageStartTime { get; set; }
public DateTimeOffset UsageEndTime { get; set; }
[JsonConverter(typeof(ResConverter))]
public InstanceData InstanceData { get; set; }
public double Quantity { get; set; }
public string MeterId { get; set; }
}
public class InstanceData
{
[JsonPropertyName("Microsoft.Resources")]
public MicrosoftResources MicrosoftResources { get; set; }
}
public class MicrosoftResources
{
public string ResourceUri { get; set; }
public string Location { get; set; }
public object Tags { get; set; }
public object AdditionalInfo { get; set; }
}
Test code and result
var jsondata = "{\"Properties\":{\"SubscriptionId\":\"sub1\",\"UsageStartTime\":\"2015-03-03T00:00:00+00:00\",\"UsageEndTime\":\"2015-03-04T00:00:00+00:00\",\"InstanceData\":\"{\\u0022Microsoft.Resources\\u0022:{\\u0022ResourceUri\\u0022:\\u0022resourceUri1\\u0022,\\u0022Location\\u0022:\\u0022Alaska\\u0022,\\u0022Tags\\u0022:null,\\u0022AdditionalInfo\\u0022:null}}\",\"Quantity\":2.4,\"MeterId\":\"meterID1\"}}";
MyModel myModel = System.Text.Json.JsonSerializer.Deserialize<MyModel>(jsondata);
If you can change the instanceData to Json instead of string like this.
{
"properties": {
"subscriptionId": "sub1",
"usageStartTime": "2015-03-03T00:00:00+00:00",
"usageEndTime": "2015-03-04T00:00:00+00:00",
"instanceData": {"Microsoft.Resources":{"resourceUri":"resourceUri1","location":"Alaska","tags":null,"additionalInfo":null}},
"quantity": 2.4000000000,
"meterId": "meterID1"
}
}
You can easily deserialize your Json using the example below.
Model Classes:
public partial class Properties
{
[JsonPropertyName("properties")]
public PropertiesClass PropertiesProperties { get; set; }
}
public partial class PropertiesClass
{
[JsonPropertyName("subscriptionId")]
public string SubscriptionId { get; set; }
[JsonPropertyName("usageStartTime")]
public DateTimeOffset UsageStartTime { get; set; }
[JsonPropertyName("usageEndTime")]
public DateTimeOffset UsageEndTime { get; set; }
[JsonPropertyName("instanceData")]
public InstanceData InstanceData { get; set; }
[JsonPropertyName("quantity")]
public double Quantity { get; set; }
[JsonPropertyName("meterId")]
public string MeterId { get; set; }
}
public partial class InstanceData
{
[JsonPropertyName("Microsoft.Resources")]
public MicrosoftResources MicrosoftResources { get; set; }
}
public partial class MicrosoftResources
{
[JsonPropertyName("resourceUri")]
public string ResourceUri { get; set; }
[JsonPropertyName("location")]
public string Location { get; set; }
[JsonPropertyName("tags")]
public object Tags { get; set; }
[JsonPropertyName("additionalInfo")]
public object AdditionalInfo { get; set; }
}
Usage:
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
class Program
{
static void Main(string[] args)
{
// escaped version, just for demo
var json =
"{\r\n \"properties\": {\r\n \"subscriptionId\": \"sub1\",\r\n \"usageStartTime\": \"2015-03-03T00:00:00+00:00\",\r\n \"usageEndTime\": \"2015-03-04T00:00:00+00:00\",\r\n \"instanceData\": {\"Microsoft.Resources\":{\"resourceUri\":\"resourceUri1\",\"location\":\"Alaska\",\"tags\":null,\"additionalInfo\":null}},\r\n \"quantity\": 2.4000000000,\r\n \"meterId\": \"meterID1\"\r\n }\r\n}";
var props = JsonSerializer.Deserialize<Properties>(json);
}
}
Props will have all of the data. I hope this helps.

JsonConvert not working on list of structures inside class

Hello i want to deserialize a class which contains a string, a bool and a List<[mystructtype>;When using JsonConvert.Deserialize<[myclass]> it deserializes the string and the bool correctly but not the List<[Struct]>.I have also changed the List<struct> with an array of structs.Both the class container and the struct are marked with Serializeable and i do not understand where the problem is.
Can anyone help me?
Struct
[Serializable]
public struct Status
{
//identifiers
public long playerId { get; set; }
public long groupId { get; set; }
public int type { get; set; }
}
Class Container
[Serializable]
class GatewayDeviceResponse
{
public bool status { get; set; } //gets deserialized good
public string message { get; set; } //gets deserialized good
public Status[] data { get; set; } // all members are defaults
}
Deserialization
IRestResponse response = client.Execute(request);
string result = Encoding.UTF8.GetString(response.RawBytes);
GatewayDeviceResponse resp = JsonConvert.DeserializeObject<GatewayDeviceResponse>(result);
return resp.data.ToList();
P.S The string is a response from a webserver,and i am using RestSharp for creating the server request and getting the response.The thing is the response string is good.The class is deserialized good excluding the collection.
What could the problem be?
P.S
The string response from the server i get is :
"{
\"status\":true,
\"message\":\"ok\",
\"data\":[
{
\"status\":{
\"playerId\":59,
\"groupId\":26,
\"type\":2,
\"deviceId\":\"abababa",
\"groupName\":\"srl\",
\"playerName\":\"Adrian\"
}
},
{
\"status\":{
\"playerId\":25,
\"groupId\":26,
\"type\":1,
\"deviceId\":\"lalal\",
\"groupName\":\"srl\",
\"playerName\":\"Alex\"
}
}
]
}"
The Status[] array elements are not supposed to be fully filled by the server response , just the 3 fields i have posted in the POCO/
I wrote a unit test as below and it passes and correctly deserialized with restsharp. Can you replace your response string and classes to check unit test still pass?
May be your class representation is not fit for your response. Take a little help from http://json2csharp.com/ and check your classes represents your json correctly.
[Test]
public void Can_Deserialize_Struct()
{
var data = "{ \"myList\":[{\"name\": \"test1234\"}] }";
JsonDeserializer json = new JsonDeserializer();
var output = json.Deserialize<MyTest>(new RestResponse { Content = data });
Assert.NotNull(output);
}
class MyTest
{
public List<MyStruct> MyList { get; set; }
}
struct MyStruct
{
public String name { get; set; }
}
According to your response string, your c# classes should represent your json as below :
public class Status
{
public int playerId { get; set; }
public int groupId { get; set; }
public int type { get; set; }
public string deviceId { get; set; }
public string groupName { get; set; }
public string playerName { get; set; }
}
public class StatusData
{
public Status status { get; set; }
}
public class GatewayDeviceResponse
{
public bool status { get; set; }
public string message { get; set; }
public List<StatusData> data { get; set; }
}
It does not related with type struct or class. You need to add another class in front of your status representation class. Because it starts as a json object in your response string.

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;`
}