exception when deserializing json object - c#

I am attempting to deserialize some simple json into the below objects
public class Car
{
public int car_id { get; set; }
public string name { get; set; }
}
public class RootObject
{
public List<Car> cars { get; set; }
}
This is the call I make
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("http://localhost/WebApiServer/Reference/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("cars").Result;
if (response.IsSuccessStatusCode)
{
HttpContent httpContent = response.Content;
string responseString = httpContent.ReadAsStringAsync().Result;
//error happens here
var deserializeObject = JsonConvert.DeserializeObject<RootObject>(responseString);
}
this is the value of response string from debugger in VS
"\"{ \\\"cars\\\": [{\\\"car_id\\\":46,\\\"name\\\":\\\"Ford-Fiesta\\\"]}}\""
and this is the exception
//exception
Error converting value "{ "cars": [{"car_id":46,"name":"Ford-Fiesta"]}}" to type 'WebApiJson.Program+RootObject'. Path '', line 1, position 62.
this is the json - I am reading it from a file
{ "cars": [{"car_id":46,"name":"Ford-Fiesta"}]}
I have run out of ideas
EDIT:
I just tried
string serializeObject = JsonConvert.SerializeObject(text);
var deserializeObject = JsonConvert.DeserializeObject<RootObject>(serializeObject);
and it is giving me the same problem
EDIT 2
my controller returning the json
public string Cars()
{
string text = System.IO.File.ReadAllText("json.txt");
string serializeObject = JsonConvert.SerializeObject(text);
Debug.WriteLine(serializeObject);
// this fails
var deserializeObject = JsonConvert.DeserializeObject<RootObject>(serializeObject);
return JsonConvert.SerializeObject(text);
}

string text = System.IO.File.ReadAllText("json.txt");
//this line is WRONG!!
string serializeObject = JsonConvert.SerializeObject(text);
//this fails because serializeObject is a double serialized string
//which you try to deserialize to RootOject
var deserializeObject = JsonConvert.DeserializeObject<RootObject>(serializeObject);
return JsonConvert.SerializeObject(text);
You are serializing string into a string.
string serializeObject = JsonConvert.SerializeObject(text);
This is wrong, you should be deserializing to an object.
RootObject obj = JsonConvert.DeserializeObject<RootObject>(text);
This is why your Deserialize fails, because you serialize your initial json into a second string, then try to deserialize it into a RootObject.
Your controller should read something like this
public RootObject Cars()
{
string text = System.IO.File.ReadAllText("json.txt");
RootObject serializeObject = JsonConvert.DeserializeObject<RootObject>(text);
return serializeObject;
}

Related

How to pass incoming integer parameter value in json request while making a POST request

Making a POST request for the API, passing incoming json body as hardcoded string. Fine with all hardcoded values, only need to pass ID based on incoming parameter incomingID (int)
Checked couple of articles/questions, but didn't any clear answer. Please suggest/guide how to replace this hardcoded value 123456 with incoming parameter value (incomingID)
Replace field in Json file with some other value
How to replace placeholders inside json string?
private void CallAPI(int incomingID)
{
const string apiURL = "API URL"; // some test API
string getInfoResult = string.Empty;
try
{
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(apiURL);
webrequest.Method = "POST";
webrequest.ContentType = "application/json";
using (var streamWriter = new StreamWriter(webrequest.GetRequestStream()))
{
string json = "{\"Information\":{\"messageHeader\":{\"message\":\"getInfo\",\"transactionDate\":\"2021-05-11T12:05:54.000\", \"transactionID\":\"2021-05-15T12:05:54.000-12345\",\"payLoadFormat\":\"V1\",\"ID\":123456}}}"; //pass this incomingID based on parameter value
streamWriter.Write(json);
}
HttpWebResponse webresponse = (HttpWebResponse)webrequest.GetResponse();
Encoding enc = System.Text.Encoding.GetEncoding("utf-8");
StreamReader responseStream = new StreamReader(webresponse.GetResponseStream(), enc);
getInfoResult = responseStream.ReadToEnd();
webresponse.Close();
}
catch (Exception ex)
{
throw ex;
}
}
To make this, you can use simple interpolation:
string json = $"{{\"Information\":{{\"messageHeader\":{{\"message\":\"getInfo\",\"transactionDate\":\"2021-05-11T12:05:54.000\", \"transactionID\":\"2021-05-15T12:05:54.000-12345\",\"payLoadFormat\":\"V1\",\"ID\":{incomingID}}}}}}}"
Note that open and close brackets should be repeated twice to escape them. But, this is weird and not so common way to make JSON strings. Better use serialization to achieve your goal. For an example, use Newtonsoft.Json nuget to (de)serialize your objects. What you need to do:
Create your models as separate classes:
PayloadFormat.cs
[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] // this string will force your enum serialize as "V1" instead of "0"
public enum PayloadFormat
{
V1,
V2,
V3
}
MessageHeader.cs
public class MessageHeader
{
public MessageHeader(string message, DateTime transactionDate, string transactionId, PayloadFormat payloadFormat, int id)
{
Message = message;
TransactionDate = transactionDate;
TransactionId = transactionId;
PayloadFormat = payloadFormat;
Id = id;
}
public string Message { get; set; }
public DateTime TransactionDate { get; set; } // change type if you need to
public string TransactionId { get; set; } // change type if you need to
public PayloadFormat PayloadFormat { get; set; } // change type if you need to
public int Id { get; set; }
}
Information.cs
public class Information
{
public Information(MessageHeader messageHeader)
{
MessageHeader = messageHeader;
}
public MessageHeader MessageHeader { get; set; }
}
Create an instance of your Information class:
var information = new Information(new MessageHeader("getInfo", DateTime.Now, $"{DateTime.Now}-12345", PayloadFormat.V1, incomingID));
Serialize your string (make sure you are using Newtonsoft.Json;):
var json = JsonConvert.SerializeObject(information);
Then use your json as you need to. The result will be:
{
"MessageHeader": {
"Message": "getInfo",
"TransactionDate": "2022-05-17T19:45:33.2161326+05:00",
"TransactionId": "17.05.2022 19:45:33-12345",
"PayloadFormat": "V1",
"Id": 5
}
}

Cannot deserialize json array into object using restsharp

here is my JSON response:
[
{
"Id": 25,
"CreateDate": "2020-09-26T12:25:27.917",
"Title": "Second TV Repair",
"categoryTitle": "Tv Repair",
"FirstName": "Sample FirsName",
"LastName": "Sample LastName"
} ]
here is my deserilizer class:
public class ServicemanHistory
{
public int Id { get; set; }
public DateTime CreateDate { get; set; }
public string Title { get; set; }
public string categoryTitle { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Here is my restsharp request method:
public static async Task<List<ServicemanHistory>> getServiceManHistory()
{
string url = "https://myapi.net";
string token = Settings.token;
var client = new RestClient(url);
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer " + token);
var response = await client.ExecuteAsync<List<ServicemanHistory>>(request);
Console.WriteLine("**** response is:" + response.Content);
if(response.IsSuccessful)
{
Console.WriteLine("SUCCESS!!!");
return response.Data;
} else
{
return null;
}
}
I get success printed in my console and I get the json returned from response.Content, but response.Data is always null. I did the same using NewtonSoft and that didn't fix it. And I tried using a wrapper for JSON array inside my deserializer class and didn't work either.
My attempt using NewtonSoft:
public static async Task<List<ServicemanHistory>> getServiceManHistory()
{
string url = "https://myapi.net";
string token = Settings.token;
var client = new RestClient(url);
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer " + token);
var response = await client.ExecuteAsync(request);
Console.WriteLine("**** response is:" + response.Content);
var result = JsonConvert.DeserializeObject<List<ServicemanHistory>>(response.Content);
if(response.IsSuccessful)
{
Console.WriteLine("SUCCESS!!!");
return result;
} else
{
return null;
}
}
I get the following error when trying to deserialize using NewtonSoft:
Newtonsoft.Json.JsonSerializationException
Message=Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List
o fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

How to deserilize array of json Object in c#

Hi I want to read Id from JSON object which returns from Web Service :
[{"id":11,"username":"test5"}]
Code:
HttpResponseMessage response = null;
using (response = httpClient.PostAsync(url, content).Result)
{
try
{
response.EnsureSuccessStatusCode(); //200 Ok
string responJsonText = response.Content.ReadAsStringAsync().Result;
JObject res = JObject.Parse(responJsonText);
//if ((int)res["id"][0] > 0)
// {
var uid = (int)res["id"][0];
if (uid > 0)
{
return uid;
}
else
{ return 0; }
// }
// else
//{ return 0; }
}
How i can read the Id and username from Json Response using C#?
I get an exception with the following message:
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path
Solution 1 - deserialize into C# models:
You can create a model that matches your json structure:
public class User
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("username")]
public string Username { get; set; }
}
And then deserialize the json string, using Newtonsoft.Json nuget package as follows:
string json = #"[{""id"":11,""username"":""test5""}]";
var users = JsonConvert.DeserializeObject<List<User>>(json);
Solution 2 - parsing the json using JArray
string json = #"[{""id"":11,""username"":""test5""}]";
JArray array = JArray.Parse(json);
int id = array.First["id"].Value<int>();
string username = array.First["username"].Value<string>();
I'm assuming the array will contain at least 1 element and there will be an id and username property. Proper error handling code should be added.

Error Json deserialization and List<>

I'm trying to deserialize some JSON response. With simple response I've no problem but with a complex response I get this error:
Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type
'System.Collections.Generic.List`1[APIEffilogics.Usuari+Node]' because
the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.
To fix this error either change the JSON to a JSON array (e.g.
[1,2,3]) or change the deserialized type so that it is a normal .NET
type (e.g. not a primitive type like integer, not a collection type
like an array or List) that can be deserialized from a JSON object.
JsonObjectAttribute can also be added to the type to force it to
deserialize from a JSON object.
It seems that I have a problem with the type of I put when deserialize the string. The JSON string is like this:
{
nodes: [
{
id: 5,
global_id: 5,
description: "Oven",
room_id: 2,
floor_id: 1,
building_id: 1,
client_id: 2,
nodemodel_id: 2,
nodetype_id: 1
},
{
id: 39,
global_id: 39,
description: "Fridge",
room_id: 2,
floor_id: 1,
building_id: 1,
client_id: 2,
nodemodel_id: 8,
nodetype_id: 1
}, ...
],
limit: 10,
offset: 0
}
And those are the classes:
public class Node : Usuari //Estructura nodes
{
[JsonProperty("limit")]
public int limit { get; set; }
[JsonProperty("offset")]
public int offset { get; set; }
[JsonProperty("nodes")]
public List<Node_sub> nodes_sub { get; set; }
}
public class Node_sub : Node
{
[JsonProperty("id")]
public string nid { get; set; }
[JsonProperty("global_id")]
public string gid { get; set; }
[JsonProperty("description")]
public string descrip { get; set; }
[JsonProperty("room_id")]
public string rid { get; set; }
[JsonProperty("floor_id")]
public string fid { get; set; }
[JsonProperty("client_id")]
public string cid { get; set; }
[JsonProperty("building_id")]
public string bid { get; set; }
[JsonProperty("nodemodel_id")]
public string model { get; set; }
[JsonProperty("nodetype_id")]
public string type { get; set; }
}
The code is:
public void Request(string url, string metode, string value)
{
try
{
//Enviem la petició a la URL especificada i configurem el tipus de connexió
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.KeepAlive = true;
myReq.Headers.Set("Cache-Control", "no-store");
myReq.Headers.Set("Pragma", "no-cache");
myReq.Headers.Set("Authorization", usuari.token_type + " " + usuari.access_token);
myReq.ContentType = "application/json";
if (metode.Equals("GET") || metode.Equals("POST"))
{
myReq.Method = metode; // Set the Method property of the request to POST or GET.
if (body == true)
{
// add request body with chat search filters
List<paramet> p = new List<paramet>();
paramet p1 = new paramet();
p1.value = "1";
string jsonBody = JsonConvert.SerializeObject(value);
var requestBody = Encoding.UTF8.GetBytes(jsonBody);
myReq.ContentLength = requestBody.Length;
//myReq.ContentType = "application/json";
using (var stream = myReq.GetRequestStream())
{
stream.Write(requestBody, 0, requestBody.Length); //Enviem el cos de la petició
}
body = false;
}
}
else throw new Exception("Invalid Method Type");
//Obtenim la resposta del servidor
HttpWebResponse myResponse = (HttpWebResponse)myReq.GetResponse();
Stream rebut = myResponse.GetResponseStream();
StreamReader readStream = new StreamReader(rebut, Encoding.UTF8); // Pipes the stream to a higher level stream reader with the required encoding format.
string info = readStream.ReadToEnd();
if (tipus == 0) jsonclient = JsonConvert.DeserializeObject<List<Usuari.Client>>(info);
else if (tipus == 1) jsonedif = JsonConvert.DeserializeObject<List<Usuari.Building>>(info);
else if (tipus == 2) jsonplanta = JsonConvert.DeserializeObject<List<Usuari.Floor>>(info);
else if (tipus == 3) jsonhab = JsonConvert.DeserializeObject<List<Usuari.Room>>(info);
else if (tipus == 4) jsonnode = JsonConvert.DeserializeObject<List<Usuari.Node>>(info);
}
catch (WebException ex)
{
// same as normal response, get error response
var errorResponse = (HttpWebResponse)ex.Response;
string errorResponseJson;
var statusCode = errorResponse.StatusCode;
var errorIdFromHeader = errorResponse.GetResponseHeader("Error-Id");
using (var responseStream = new StreamReader(errorResponse.GetResponseStream()))
{
errorResponseJson = responseStream.ReadToEnd();
}
//var errorCode = JsonObject.Parse(errorResponseJson).Object("responseStatus")["errorCode"];
//var errorMessage = JsonObject.Parse(errorResponseJson).Object("responseStatus")["message"];
}
}
Why I'm having this error? List<Usuari.Node> is an array that contains all the items of JSON message. I try to fix the error but I'm not able to find and answer. How can I fix it?
Thanks
The service returns just one Node, instead of an array of Nodes with one element. To solve this problem, you can use one of these approaches:
Change the service so it always returns an array (by wrapping the result before returning it).
If 1. is not an option: Differentiate the different response types in the client (check if the response is an array and if not, tell the serializer to parse a single Node instead of a list) and either handle the single object differently or just wrap it in a list and then proceed as if the server returned it like that.

Deserialize JSON string to c# object

My Application is in Asp.Net MVC3 coded in C#.
This is what my requirement is. I want an object which is in the following format.This object should be achieved when I deserialize the Json string.
var obj1 = new { arg1=1,arg2=2 };
After using the below code:
string str = "{\"Arg1\":\"Arg1Value\",\"Arg2\":\"Arg2Value\"}";
JavaScriptSerializer serializer1 = new JavaScriptSerializer();
object obje = serializer1.Deserialize<object>(str);
The object what i get i.e obje does not acts as obj1
Here, in this example my JSON string is static, but actually JSON string is going to be dynamically generated runtime, so i won't be able get Arg1 and Arg2 all the time.
I think the JavaScriptSerializer does not create a dynamic object.
So you should define the class first:
class MyObj {
public int arg1 {get;set;}
public int arg2 {get;set;}
}
And deserialize that instead of object:
serializer.Deserialize<MyObj>(str);
Not testet, please try.
Use this code:
var result=JsonConvert.DeserializeObject<List<yourObj>>(jsonString);
I believe you are looking for this:
string str = "{\"Arg1\":\"Arg1Value\",\"Arg2\":\"Arg2Value\"}";
JavaScriptSerializer serializer1 = new JavaScriptSerializer();
object obje = serializer1.Deserialize(str, obj1.GetType());
This may be useful:
var serializer = new JavaScriptSerializer();
dynamic jsonObject = serializer.Deserialize<dynamic>(json);
Where "json" is the string that contains the JSON values. Then to retrieve the values from the jsonObject you may use
myProperty = Convert.MyPropertyType(jsonObject["myProperty"]);
Changing MyPropertyType to the proper type (ToInt32, ToString, ToBoolean, etc).
solution :
public Response Get(string jsonData) {
var json = JsonConvert.DeserializeObject<modelname>(jsonData);
var data = StoredProcedure.procedureName(json.Parameter, json.Parameter, json.Parameter, json.Parameter);
return data;
}
model:
public class modelname {
public long parameter{ get; set; }
public int parameter{ get; set; }
public int parameter{ get; set; }
public string parameter{ get; set; }
}
Same problem happened to me. So if the service returns the response as a JSON string you have to deserialize the string first, then you will be able to deserialize the object type from it properly:
string json= string.Empty;
using (var streamReader = new StreamReader(response.GetResponseStream(), true))
{
json= new JavaScriptSerializer().Deserialize<string>(streamReader.ReadToEnd());
}
//To deserialize to your object type...
MyType myType;
using (var memoryStream = new MemoryStream())
{
byte[] jsonBytes = Encoding.UTF8.GetBytes(#json);
memoryStream.Write(jsonBytes, 0, jsonBytes.Length);
memoryStream.Seek(0, SeekOrigin.Begin);
using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(memoryStream, Encoding.UTF8, XmlDictionaryReaderQuotas.Max, null))
{
var serializer = new DataContractJsonSerializer(typeof(MyType));
myType = (MyType)serializer.ReadObject(jsonReader);
}
}
4 Sure it will work.... ;)

Categories

Resources