Newtonsoft.Json: Invalid character after parsing property name. Expected ':' but got: , - c#

After the project update to .NET 6 from .NET Core 3.1 the Newtonsoft package fails to deserialize object. The error that I'm getting is :
System.Private.CoreLib: Exception while executing function: ExportOrder. Newtonsoft.Json: Invalid character after parsing property name. Expected ':' but got: ,. Path '', line 1, position 39.
var message = JsonConvert.DeserializeObject<OrderRequest>(myQueueItem);
The OrderRequest class:
public class OrderRequest
{
[JsonProperty]
public string RunId
{
get;
set;
}
}
And the myQueueItem that I'm sending is:
{
"input": "{\"06-24T07-05-35Z48\",\"IsSuccess\":true,\"Message\":\"Completed Successfully\"}"
}
Is it better idea to migrate to System.Text.JSON ?

you json is not valid, it should be
var json="{\"input\": \"06-24T07-05-35Z48\",\"IsSuccess\":true,\"Message\":\"Completed Successfully\"}";
OrderRequest orderRequest=JsonConvert.DeserializeObject<OrderRequest>(json);
string message = orderRequest.Message; //Completed Successfully
class
public class OrderRequest
{
[JsonProperty("input")]
public string Input { get; set; }
public bool IsSuccess { get; set; }
public string Message { get; set; }
}

Related

error parsing json in asp.net mvc login project

i am fetching data from an asp.net webapi and storing it as
var token = string.Empty;
var result = resMessage.Content.ReadAsStringAsync().Result;
token = JsonConvert.DeserializeObject<string>(result);
value of result is
{
value: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwibmJmIjoxNjMzODY1NzE0LCJleHAiOjE2MzM4Njc1MTQsImlhdCI6MTYzMzg2NTcxNH0.2Vje7sXWw4tb_h50cR3zdI5TDIjOiWR-94_i2mH40cg",
formatters: [ ],
contentTypes: [ ],
declaredType: null,
statusCode: 200
}
the error i am getting
JsonReaderException: Unexpected character encountered while parsing value: {. Path '', line 1, position 1.
in this line
token = JsonConvert.DeserializeObject<string>(result);
i am not able to understand what is going on. i have written this code in asp.net mvc project
You're trying to deserialise a string into a string here, which won't work as they're the exact same type.
You need to deserialise string result into a concrete type, which JsonConvert.DeserializeObject should be aware of, to deserialise it as such.
This should work:
public class Data
{
public string value { get; set; }
public List<object> formatters { get; set; }
public List<object> contentTypes { get; set; }
public object declaredType { get; set; }
public int statusCode { get; set; }
}
Data token = JsonConvert.DeserializeObject<Data>(result);

How to serialize this C# return value into a JSON object?

I have this object value that is being returned and I would like to convert it into a useful JSON object that I can inspect and manipulate. Ultimately, my goal is to validate the values of username and accessKey. But 2 things are throwing this off. Double {{ makes it invalid JSON and sauce:options can't be converted into a property in a class.
{{
"browserName": "MicrosoftEdge",
"browserVersion": "latest",
"platformName": "Windows 10",
"sauce:options": {
"username": "test",
"accessKey": "123"
}
}}
Here is what I tried:
string output = JsonConvert.SerializeObject(SauceSession.Options.ConfiguredEdgeOptions);
This SauceSession.Options.ConfiguredEdgeOptions returns that object I mentioned above.
Got this back:
Newtonsoft.Json.JsonSerializationException: 'Error getting value from 'BinaryLocation' on 'OpenQA.Selenium.Edge.EdgeOptions'.'
I also tried this as per suggestions:
var serialized = JsonConvert.SerializeObject(SauceSession.Options.ConfiguredEdgeOptions);
And got back this Newtonsoft.Json.JsonSerializationException: 'Error getting value from 'BinaryLocation' on 'OpenQA.Selenium.Edge.EdgeOptions'.'
Since you cannot fix the source, you're going to have to apply a bodge to fix the JSON, for example this will work:
var fixedJson = sourceJson.Substring(1, Json.Length - 2);
Now you should have a couple of classes to hold your data, this way you can also cope with the unusual names:
public class Root
{
public string BrowserName { get; set; }
public string BrowserVersion { get; set; }
public string PlatformName { get; set; }
[JsonProperty("sauce:options")]
public Options SauceOptions { get; set; }
}
public class Options
{
public string Username { get; set; }
public string AccessKey { get; set; }
}
And now you should be able to deserialise like this:
var root = JsonConvert.DeserializeObject<Root>(fixedJson);

Parsing JSON from API - C#

I am requesting a JSON from a standard web service and I need to handle the response so I can work with the objects. I am working in Xamarin Studio - not that i think that matters.
You can see a result from web service by:
https://dawa.aws.dk/vejnavne/autocomplete?q=due
This is requesting street names in Denmark with 'due' in it.
public async Task doAsyncAddress(string input)
{
var template = "https://dawa.aws.dk/vejnavne/autocomplete?q={0}";
var url = string.Format(template, input);
using (var httpClient = new HttpClient())
{
try
{
Task<HttpResponseMessage> getResponse = httpClient.GetAsync(url);
HttpResponseMessage response = await getResponse;
var responseJsonString = await response.Content.ReadAsStringAsync();
/*
I have tried different things here, with with JsonConvert and JObject but neither works.. I have an idea that the son string is in wrong format, with "\n" included and i have tried to remove these, but still without results. I can see the string so I know it is there.. But it is not formatted correctly.
*/
}
catch (Exception ex)
{
string message = ex.Message;
return message;
}
}
}
With the JsonConverter.DeserializeObject i do this:
var adress = JsonConvert.DeserializeObject<List<Address>>(responseJsonString);
where Address:
public class Address
{
public string tekst { get; set; }
public List<Vejnavne> vejnavn
{ get; set; }
}
public class Vejnavne
{
public string href { get; set; }
public string navn { get; set; }
}
and the response is:
"Cannot deserialize the current JSON object (e.g.
{\"name\":\"value\"}) into type
'System.Collections.Generic.List`1[MinEjendom.Vejnavne]' because the
type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.\nTo 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 frenter code hereom a JSON object.\nPath
'[0].vejnavn.href', line 5, position 11.”
And with JObject i get:
"Error reading JObject from JsonReader. Current JsonReader item is not
an object: StartArray. Path '', line 1, position 1."
Your C# code is wrong. This is the correct one:
public class Vejnavn
{
public string href { get; set; }
public string navn { get; set; } // not List<Vejnavne> vejnavn
}
public class Address
{
public string tekst { get; set; }
public Vejnavn vejnavn { get; set; }
}
Then call it like this:
var adress = JsonConvert.DeserializeObject<List<Address>>(responseJsonString);
When you've JSON, you are .NET developer and finally - you have to convert JSON to C# class, you should use Edit - > Paste Special -> Paste JSON as classes. This is an awesome tool :)
Your code is wrong. This is the generated class from your JSON :
public class Class1
{
public string tekst { get; set; }
public Vejnavn vejnavn { get; set; }
}
public class Vejnavn
{
public string href { get; set; }
public string navn { get; set; }
}
When you have successfully generated your code, you can rename the class.

LINQ to JSON - Newtonsoft.Json.Linq.JProperty Error

The following is my json string:
string json = #"{
'?xml' : {
'#version' : '1.0',
'#encoding' : 'UTF-8'
},
'DataFeed' : {
'#FeedName' : 'AdminData',
'Issuer' : {
'id' : '95',
'name' : 'Apple',
'symbol' : 'AAPL'
}
}
}";
When I try to do the following LINQ query:
JObject feed = JObject.Parse(json);
var compInfo = feed["DataFeed"]["Issuer"]
.Select(c => c["name"]);
I get the following error:
`Cannot access child value on Newtonsoft.Json.Linq.JProperty.`
However, the following works fine:
var test1 = feed["DataFeed"]["Issuer"]["name"];
Any idea why I can't use LINQ on this json string?
Think about what your JSON is. You're selecting from a dictionary so the result in the LINQ is the property. You're trying to then access "name" on a property which doesn't make sense which gives you the error.
You already have the working code:
var test1 = feed["DataFeed"]["Issuer"]["name"];
You can get the value you want using two methods:
Method 1:
First you need a cast from JToken to a JObject since the value of 'Issuer' is an object:
var compInfo = (JObject)feed["DataFeed"]["Issuer"];
Then loop through all the properties to find the one with the name "Name" then get its value as a string:
var str = compInfo.Properties().First(x => x.Name == "name").ToObject<string>();
// str will contain the value 'Apple'.
Method 2:
You can also deserialize the JSON into an object that is easier to handle. To do that first you'll need to create a .net object "equivalent" of your JSON . You can use Visual Studio to generate these for you from the Edit menu -> Paste Special -> Paste JSON as classes or use a website like JsonUtils.com
public class Xml
{
[JsonProperty("#version")]
public string Version { get; set; }
[JsonProperty("#encoding")]
public string Encoding { get; set; }
}
public class Issuer
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("symbol")]
public string Symbol { get; set; }
}
public class DataFeed
{
[JsonProperty("#FeedName")]
public string FeedName { get; set; }
[JsonProperty("Issuer")]
public Issuer Issuer { get; set; }
}
public class RootJsonObject
{
[JsonProperty("?xml")]
public Xml Xml { get; set; }
[JsonProperty("DataFeed")]
public DataFeed DataFeed { get; set; }
}
Then all you have to do to get the Issuer name is this:
var feed = JsonConvert.DeserializeObject<RootJsonObject>(json);
var issuer = feed.DataFeed.Issuer.Name;

Deserializing OData.Error messages

I have an ASP.NET application that uses the Azure AD Graph API. Often, when an invalid operation is performed against the Graph API, an exception is thrown.
The following code shows an invalid Graph API call that would trigger an exception:
// Query the Azure AD User
var userToUpdate = await activeDirectoryClient.Users.GetByObjectId("user#domain.net").ExecuteAsync();
// Set given name to an empty string (not allowed)
userToUpdate.GivenName = "";
try
{
// Update the user in Azure AD
await userToUpdate.UpdateAsync();
}
catch (Exception e)
{
// Return exception message
}
The message of the inner exception is a JSON string with forward slashes before each quotation mark. It looks something like this:
"{\"odata.error\":{\"code\":\"Request_BadRequest\",\"message\":{\"lang\":\"en\",\"value\":\"Invalid value specified for property 'givenName' of resource 'User'.\"},\"values\":[{\"item\":\"PropertyName\",\"value\":\"givenName\"},{\"item\":\"PropertyErrorCode\",\"value\":\"InvalidValue\"}]}}"
Attaching a screenshot of the Locals window where the exception message is found:
I would like to convert this JSON to a .NET object to return informative error details. I am using the JSON.NET library for this, and I am assuming that the JSON will deserialize to an ODataError object:
var error = Newtonsoft.Json.JsonConvert.DeserializeObject<ODataError>(e.InnerException.Message);
However, the deserialized object always has a value of null, which means that the conversion is not working as expected.
That being said, what class should the above JSON string map to? Also, should I be removing the forward slashes from the string for proper deserialization?
The reason you've got null after deserialization is your JSON object properties names differs from Microsoft.Azure.ActiveDirectory.GraphClient.ODataError class properties names - "odata.error" property can not be deserialized to Error property of Microsoft.Azure.ActiveDirectory.GraphClient.ODataError
As workaround I've added my own types for correct deserialization:
internal class ODataError
{
[JsonProperty("odata.error")]
public ODataErrorCodeMessage Error { get; set; }
}
internal class ODataErrorCodeMessage
{
public string Code { get; set; }
public ODataErrorMessage Message { get; set; }
public List<ExtendedErrorValue> Values { get; set; }
}
internal class ExtendedErrorValue
{
public string Item { get; set; }
public string Value { get; set; }
}
internal class ODataErrorMessage
{
public string Lang { get; set; }
public string Value { get; set; }
}
After that JSON message was properly deserialized:
...
try
{
await ADClient.Users.AddUserAsync(newUser);
return Result.Ok();
}
catch (DataServiceRequestException ex)
{
var innerException = ex.InnerException;
var error = JsonConvert.DeserializeObject<ODataError>(innerException.Message);
return Result.Fail(new Error(error.Error.Message.Value, error.Error.Code, ex));
}

Categories