I want to parse json data. Below is my json response.
{
"error": true,
"errors": {
"email": [
"Enter a valid email address."
]
}
}
Below is my sample code.
JObject obj = JObject.Parse(res);
string Status = (string)obj["error"];
if (Status == "True" || Status == "true")
{
string email = obj["errors"]["email"].ToString();
MessageBox.Show(email );
return;
}
but I am getting email value is '["Enter a valid email address."]'.
I want to remove '[]'. How to do this?
Unless your schema is dynamic you're almost always better off going with a type-safe approach i.e.:
public class Errors
{
public string[] email { get; set; }
}
public class MyData
{
public bool error { get; set; }
public Errors errors { get; set; }
}
And then deserializing like this:
var json = "{\"error\": true, \"errors\": { \"email\": [\"Enter a valid email address.\"]}}";
var data = JsonConvert.DeserializeObject<MyData>(json);
email in the sample json given in OP, is an array. If you need to access all values in the array, you need to loop through each element in the array. For example
foreach(var emailValue in obj["errors"]["email"])
{
string email = (string)emailValue;
// do rest
}
If you only need the first element in the array, you could use
var email = (string)obj["errors"]["email"][0];
Related
I am trying to compare json value and based on that i want to update the existing value,for example, currently we have "value" : [r0] in json, i want to compare and if value : [r0] ,then update it to [r0,r1] but iam hiting error that it cannot compare and there is a cast issue, could someone suggest what could be done
public void updateJsonParameter(string file)
{
try
{
var list = new List<string> { "joe", "test" };
JArray array = new JArray(list);
var jobject = JObject.Parse(file);
var ringvalue = (string)jobject["properties"]["parameters"]["ringValue"]["value"]; // unable to case here and compare
jobject["properties"]["parameters"]["ringValue"]["value"] = array; // able to update value but i want to update after comparing the existing values
var result = JsonConvert.SerializeObject(jobject);
}
following is the json format
{
"properties": {
"displayName": "jayatestdefid",
"description": "test assignment through API",
"metadata": {
"assignedBy": "xyz#gmail.com"
},
"policyDefinitionId": "/providers/Microsoft.Management/managementgroups/MGTest/providers/Microsoft.Authorization/policyDefinitions/test",
"parameters": {
"ringValue": {
"value": ["r0"]
}
},
"enforcementMode": "DoNotEnforce",
}
}
jobject.properties.parameters.ringValue.value is an array ["r0"] with one element "r0". If you want to check if it's an array with one element and that element is "r0", do exactly that:
var ringvalue = jobject["properties"]["parameters"]["ringValue"]["value"];
if(ringvalue.length == 1 && ringvalue[0] == "r0")
jobject["properties"]["parameters"]["ringValue"]["value"] = array;
You could compare the ringvalue (which is an JArray) using JArray.DeepEquals and then replace if the comparison returns true. For example,
var list = new List<string> { "joe", "test" };
JArray array = new JArray(list);
JArray valueToCompare = new JArray(new[]{"r0"});
var ringvalue = (JArray)jobject["properties"]["parameters"]["ringValue"]["value"];
if(JArray.DeepEquals(ringvalue,valueToCompare))
{
jobject["properties"]["parameters"]["ringValue"]["value"] = array;
}
First, as Klaycon said in his answer, it's worth noting that your "value" is not a single string. In json, whenever you see [ and ] then you have a collection, or an array, or a list.
When I work with json strings, I always like to be able to convert them into a strongly typed object. There is a very handy online tool I use all the time: http://json2csharp.com/
I took your json string that you provided and pasted it into that website. Here is that your object(s) look like when converted into c# classes:
public class RootObject // You can name this whatever you want
{
public Properties properties { get; set; }
}
public class Metadata
{
public string assignedBy { get; set; }
}
public class RingValue
{
public List<string> value { get; set; }
}
public class Parameters
{
public RingValue ringValue { get; set; }
}
public class Properties
{
public string displayName { get; set; }
public string description { get; set; }
public Metadata metadata { get; set; }
public string policyDefinitionId { get; set; }
public Parameters parameters { get; set; }
public string enforcementMode { get; set; }
}
Now, we can easily do the logic you need as follows:
// This is your json string, escaped and turned into a single string:
string file = "{ \"properties\": { \"displayName\": \"jayatestdefid\", \"description\": \"test assignment through API\", \"metadata\": { \"assignedBy\": \"xyz#gmail.com\" }, \"policyDefinitionId\": \"/providers/Microsoft.Management/managementgroups/MGTest/providers/Microsoft.Authorization/policyDefinitions/test\", \"parameters\": { \"ringValue\": { \"value\": [\"r0\"] } }, \"enforcementMode\": \"DoNotEnforce\", }}";
// Convert your json string into an instance of the RootObject class
RootObject jobject = JsonConvert.DeserializeObject<RootObject>(file);
// Get a list of all the "values"
List<string> values = jobject.properties.parameters.ringValue.value;
// Loop over your colleciton of "value" and do your logic
for (int i = 0; i < values.Count; ++i)
{
if (values[i] == "r0")
{
values[i] = "r0,r1";
}
}
// And finally, turn your object back into a json string
var result = JsonConvert.SerializeObject(jobject);
And this is the final result:
{
"properties":{
"displayName":"jayatestdefid",
"description":"test assignment through API",
"metadata":{
"assignedBy":"xyz#gmail.com"
},
"policyDefinitionId":"/providers/Microsoft.Management/managementgroups/MGTest/providers/Microsoft.Authorization/policyDefinitions/test",
"parameters":{
"ringValue":{
"value":[
"r0,r1"
]
}
},
"enforcementMode":"DoNotEnforce"
}
}
I have this JSON string but are not sure how I will parse out the values that are inside:
has
has2
I do succeed to parse out the "id" correctly but are not sure how to access:
CORS
CORS2
CORS3
CORS4
I get the error:
'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.String[]' because the type requires a JSON array (e.g. [1,2,3])
I have pasted the JSON in the pastebin:
https://pastebin.com/iWgGV9VK
The code I have:
public void getInfo()
{
String JSONstring = "{ id: 'hello', name: 'Hello',has:{ CORS: false,CORS2: true},has2:{ CORS3: false,CORS4: true}}";
String id = ""; List<String> has = new List<String>(); List<String> has2 = new List<String>();
var deserializedTicker = JsonConvert.DeserializeObject<JsonInfo>(JSONstring);
id = deserializedTicker.id;
has = deserializedTicker.has.ToList();
has2 = deserializedTicker.has.ToList();
}
public class JsonInfo
{
public String id { get; set; }
public String[] has { get; set; }
public String[] has2 { get; set; }
}
I am trying with the dynamic approach using an object but gets an error here also:
''Newtonsoft.Json.Linq.JValue' does not contain a definition for 'id''
//responseBody holds the JSON string
dynamic stuff = JsonConvert.DeserializeObject(responseBody);
foreach (var info in stuff)
{
dynamic id = info.Value.id; //''Newtonsoft.Json.Linq.JValue' does not contain a definition for 'id''
dynamic has = info.Value.has;
dynamic has2 = info.Value.has2;
if (has != null && has2 != null)
{
dynamic cors = has.CORS;
if(cors != null)
{
MessageBox.Show(cors.ToString());
}
}
}
First off, let's correct your JSON:
{
"id": "hello",
"name": "Hello",
"has": {
"CORS": false,
"CORS2": true
},
"has2": {
"CORS3": false,
"CORS4": true
}
}
Now, the problem you are experiencing is because you are attempting to deserialize the value in "has" and "has2" as arrays. In the JSON, they are not arrays; they are objects. As such, you need to define new classes with the same properties so the JSON can be properly deserialized:
public class JsonInfo
{
public string id { get; set; }
public string name { get; set; }
public JsonHasInfo has { get; set; }
public JsonHas2Info has2 { get; set; }
}
public class JsonHasInfo
{
public bool CORS { get; set; }
public bool CORS2 { get; set; }
}
public class JsonHas2Info
{
public bool CORS3 { get; set; }
public bool CORS4 { get; set; }
}
Now you should be able to deserialize the (correct) JSON properly:
String JSONstring = "{ \"id\": \"hello\", \"name\": \"Hello\", \"has\": { \"CORS\": false, \"CORS2\": true }, \"has2\": { \"CORS3\": false, \"CORS4\": true } }\";"
var deserializedTicker = JsonConvert.DeserializeObject<JsonInfo>(JSONstring);
You json was incorrect, the key has contains a dict no list.
You need change your deserialize to dictionary or change your json.
Here you can see an example:
https://json-schema.org/understanding-json-schema/reference/array.html#array
In your JSON, has is an object, not an array. You should model your class to support an object containing the attributes CORS, CORS2, and so on, and so forth.
Edit: If you want to stick to has being an array, you should change your JSON to match what an array expects, which could be like: has: [ false, true ], and omit the CORS thing.
Is there a way to declare a class where for a specific variable I can receive either a List or a string?
I trying to deserialize a JSON and it can come in one of the formats below:
"MercadoriasPresencaCarga": {
"Mercadoria": 7693066,
"Descarga": "08/07/2017 13:35:39"
},
or
"MercadoriasPresencaCarga": {
"Mercadoria": [
"7693066"
],
"Descarga": [
"08/07/2017 13:35:39"
]
},
The class for this block is created like this:
public class MercadoriasPresencaCarga
{
public List<string> Mercadoria { get; set; }
public List<string> Descarga { get; set; }
}
The problem is that if this block of JSON come as the first format that I showed where it is not a array, it will cause an error on it deserialization.
How could I solve this problem?
Ideally the json should always come in the same format, but if that's not a possibility there are some workarounds.
Both json strings will deserialize successfully using the following class:
public class Model
{
// other properties here
// ....
[JsonIgnore]
public string Mercadoria => GetValue("Mercadoria");
[JsonIgnore]
public string Descarga => GetValue("Descarga");
public JObject MercadoriasPresencaCarga { get; set; }
private string GetValue(string path)
{
if (MercadoriasPresencaCarga == null)
{
return null;
}
string value = null;
JToken token = MercadoriasPresencaCarga.SelectToken(path);
if (token.Type == JTokenType.Array && token.HasValues)
{
value = token.First.Value<string>();
}
else
{
value = token.Value<string>();
}
return value;
}
}
Please note that:
MercadoriasPresencaCarga will be deserialized as JObject
Both Mercadoria and Descarga are non-serializable properties (marked with [JsonIgnore])
Testing the code - json string with string properties (no arrays):
string json1 = #"{
""MercadoriasPresencaCarga"": {
""Mercadoria"": 7693066,
""Descarga"": ""08/07/2017 13:35:39""
}
}";
Model model1 = JsonConvert.DeserializeObject<Model>(json1);
Console.WriteLine($"Descarga: {model1.Descarga}, Mercadoria: {model1.Mercadoria}");
Testing the code - json string with arrays:
string json2 = #"{
""MercadoriasPresencaCarga"": {
""Mercadoria"": [
""7693066""
],
""Descarga"": [
""08/07/2017 13:35:39""
]
}
}";
Model model2 = JsonConvert.DeserializeObject<Model>(json2);
Console.WriteLine($"Descarga: {model2.Descarga}, Mercadoria: {model2.Mercadoria}");
So, please read this detail for more information. I get error at
Method not found: 'System.String System.String.Format(System.IFormatProvider, System.String, System.Object)'. when i try get value of items of array.
The array is:
{
[
{
"GROUP_MOD_ID": "G06",
"ADMIN": 1,
"USERS": 0
}
]
}
This is snippet code
dynamic obj_str = JsonConvert.DeserializeObject(obj);
string value_admin = obj_str["ADMIN"];
Console.WriteLine(value_admin);
if (value_admin == "1")
return true;
else
return false;
. Thank all.
I wouldn't use dynamic in this case. I generally recommend avoiding dynamic in C#. Instead I prefer the JToken-style approach (in the Newtonsoft.Json.Linq namespace, though it doesn't mean you have to use Linq):
JArray array = JArray.Parse( input );
JObject firstObject = (JObject)array.First;
String adminValue = (String)firstObject.GetValue("ADMIN");
In production you'll want to add input validation code to ensure the input JSON array and object actually has elements and values and handle those errors accordingly.
But if you're certain that the input is correct you can reduce this down to a single-line:
String adminValue = (String)( ((JObject)JArray.Parse( input )).First.GetValue("ADMIN") );
...at the cost of readbility, of course.
First of all your JSON seems to be incorrect.
Correct JSON:
[{
"GROUP_MOD_ID": "G06",
"ADMIN": 1,
"USERS": 0
}]
And when you desialize this json, it will give you array of array.
You code will be:
dynamic obj_str = JsonConvert.DeserializeObject(json);
string value_admin = obj_str[0].ADMIN;
Console.WriteLine(value_admin);
if (value_admin == "1")
{
}
else
{
}
You can see this by doing this way to.
public class SampleClass
{
public string GROUP_MOD_ID { get; set; }
public int ADMIN { get; set; }
public int USERS { get; set; }
}
Code to deserialize:
SampleClass[] obj_str = JsonConvert.DeserializeObject<SampleClass[]>(json);
int value_admin = obj_str[0].ADMIN;
Console.WriteLine(value_admin);
if (value_admin == 1)
{
}
else
{
}
Your code would work only if you have json as
var obj="{'GROUP_MOD_ID':'G06','ADMIN':10,'USERS':0}";
or
var obj="[{'GROUP_MOD_ID':'G06','ADMIN':1,'USERS':0}]";
dynamic obj_str = JsonConvert.DeserializeObject(obj);
string value_admin = obj_str[0]["ADMIN"];
Console.WriteLine(value_admin);
Hi first of you make model for Deserialize Object.
Your model like this.
public class Test_Model
{
[JsonProperty("GROUP_MOD_ID")]
public string GROUP_MOD_ID { get; set; }
[JsonProperty("ADMIN")]
public int ADMIN { get; set; }
[JsonProperty("USERS")]
public int USERS { get; set; }
}
and after write this code:
var obj_str = JsonConvert.DeserializeObject<Test_Model>(obj);
int value_admin = obj_str.ADMIN;
Console.WriteLine(value_admin);
if (value_admin == 1)
return true;
else return false;
I hope so your problem sort out.
Hi I'm trying to parse a JSON page in C#, but I can't seem to read some strings, like:
"versions": [
{
"date": 1340466559,
"dl_link": "http://dev.bukkit.org/media/files/599/534/NoSwear.jar",
"filename": "NoSwear.jar",
"game_builds": [
"CB 1.2.5-R4.0"
],
"hard_dependencies": [],
"md5": "d0ce03e817ede87a9f76f7dfa67a64cb",
"name": "NoSwear v5.1",
"soft_dependencies": [],
"status": "Semi-normal",
"type": "Release"
},
How could I read that?
This is the code I have right now and works for everything else except this:
public static void GetMoreInfo(string plugin)
{
try
{
string url = "http://bukget.org/api/plugin/";
var wc = new WebClient();
var json = wc.DownloadString(url + plugin);
var moreInfo = JsonConvert.DeserializeObject<MoreInfo>(json);
foreach (var category in moreInfo.categories)
{
Categories += category + ", ";
}
Categories = Categories.Remove(Categories.Length - 2, 2);
}
catch (Exception)
{
}
finally
{
if (string.IsNullOrEmpty(Categories))
{
Categories = "No data found.";
}
}
}
public class MoreInfo
{
public string[] categories;
}
How about handling your json dynamically, instead of deserializing to a concrete class?
var wc = new WebClient();
var json = wc.DownloadString("http://bukget.org/api/plugin/test");
dynamic moreInfo = JsonConvert.DeserializeObject(json);
Console.WriteLine("{0} {1} {2}", moreInfo.name, moreInfo.desc, moreInfo.status);
string categories = String.Join(",", moreInfo.categories);
Console.WriteLine(categories);
Or would you prefer the classical approach?
var plugin = JsonConvert.DeserializeObject<Plugin>(json);
string categories = String.Join(",",plugin.categories);
public class Plugin
{
public List<string> authors;
public string bukkitdev_link;
public List<string> categories;
public string desc;
public string name;
public string plugin_name;
public string status;
public List<Version> versions;
}
public class Version
{
public string date;
public string filename;
public string name;
//.......
}
I could be wrong, but the JSON you're receiving is an array named versions but you're trying to deserialize it into a MoreInfo object that exposes an array named categories (unless it's just a typo in your example). Have you tried renaming MoreInfo.categories to MoreInfo.versions?
UPDATE
I don't think that would make a difference because the JSON converter doesn't know what to do with each object in the array. You need to provide an object to deserialize each element in the JSON array.
For example, try modifying the MoreInfo object to include matching properties to the JSON string (the elements in the array)
[DataContract]
public class MoreInfo
{
[DataMember]
public DateTime date { get; set; }
[DataMember]
public string dl_link { get; set; }
...
}
And then try to deserialize the JSON string to a List<MoreInfo>:
JsonConverter.DeserializeObject<List<MoreInfo>>(json)
You will then have to modify the rest of your code to work with MoreInfo objects and not strings in an array.
REFER TO THIS ANSWER
See this question, the accepted answer should help you solve your problem: Json.NET: Deserialization with list of objects