accessing dictionary from a Json string in c# - c#

I have a JSON string as a response from server which contains key value pairs like dictionary. Some of the keys can have dictionary as their values as well. I have to access values based on certain keys from the inner dictionary. How can i access them and store in a string?
Something like this:-
string JsonData = "{\"status\":\"BAD_REQUEST\",\"code\":400,\"errorsCount\":1,\"errors\":[{\"desciption\":\"Field cannot be blank\"}]}";
string toBeAccessedValue = Field cannot be blank;
Any help would be appreciated.

You can use [JsonExtensionData] to deserialize your json to class object.
public class RootObject
{
[JsonExtensionData]
public Dictionary<string, JToken> data { get; set; }
}
And you can use above class like
RootObject ro = JsonConvert.DeserializeObject<RootObject>(JsonData);
var errors = ro.data["errors"].ToObject<JObject[]>();
string description = errors.FirstOrDefault().Property("desciption").Value?.ToString();
Console.WriteLine("description: " + description);
Console.ReadLine();
Alternative:
You can use below class structure that can be helpful to you to deserialize your json and retrieve any value that you want.
public class Error
{
public string desciption { get; set; }
}
public class RootObject
{
public string status { get; set; }
public int code { get; set; }
public int errorsCount { get; set; }
public List<Error> errors { get; set; }
}
And you can use above class structure to deserealize your json like
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(JsonData);
string description = rootObject.errors.FirstOrDefault()?.desciption;
Console.WriteLine("description: " + description);
Console.ReadLine();
Edit:
If you want to deserialize your json with JavaScriptSerializer then.
JavaScriptSerializer serializer = new JavaScriptSerializer();
RootObject rootObject = serializer.Deserialize<RootObject>(JsonData);
string description = rootObject.errors.FirstOrDefault()?.desciption;
Console.WriteLine("description: " + description);
Console.ReadLine();
Output:

Related

Serialize & Deserialize a dictionary that contain a class key

Im trying to serialize my dictionary that looks like that:
private Dictionary<MetaDataKey, User> _dictionary;
where MetaDataKey and Users classes looks like that:
internal class User
{
public string UserName { get; set; }
public string UserPassword { get; set; }
public List<Account> Accounts { get; set; }
}
internal class Account
{
public string Subject { get; set; }
public string AccName { get; set; }
public string AccPass { get; set; }
public List<string> Notes { get; set; }
}
internal class MetaDataKey
{
public string Name { get; set; }
public string Password { get; set; }
}
I am trying to save\load the dictionary to\from a json file like this:
private void DictionaryInit()
{
//gets the dictionary file if exists, create an empty one if not.
string path = Directory.GetCurrentDirectory() + "\\dic.json";
if (!File.Exists(path))
{
_dictionary = new Dictionary<MetaDataKey, User>();
return;
}
using (StreamReader r = new StreamReader(path))
{
string json = r.ReadToEnd();
_dictionary = JsonConvert.DeserializeObject<Dictionary<MetaDataKey, User>>(json);
}
}
public void DictionarySave()
{
//save the dictionary into dic.json file
string path = Directory.GetCurrentDirectory() + "\\dic.json";
string json = JsonConvert.SerializeObject(_dictionary);
File.WriteAllText(path, json);
}
when I am loading a new record to the dictionary and trying to save it I get:
{"WpfApplication2.MetaDataKey":{"UserName":"Enter Name","UserPassword":"Enter Password","Accounts":null}}
instead of:
{"WpfApplication2.MetaDataKey":{"Name":"Enter Name","Password":"Enter Password"},"WpfApplication2.User":{"UserName":"Enter Name","UserPassword":"Enter Password","Accounts":null}}
as you can tell, I am getting the fields of Users in MetaDataKey class.
even after I fix it manualy I am still getting exception:
An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code
when I am trying to load a non-empty file.
In conclusion, 2 problems:
1. bad json saving.
2. bad json loading
From the documentation of Json.Net:
When serializing a dictionary, the keys of the dictionary are converted to strings and used as the JSON object property names. The string written for a key can be customized by either overriding ToString() for the key type or by implementing a TypeConverter. A TypeConverter will also support converting a custom string back again when deserializing a dictionary.
You have two options:
like the documentation suggests: create a TypeConverter for your MetaDataKey and link it with attribute ([TypeConverter(typeof(MetaDataKeyConverter))]) - This is not trivial as you will have to convert the MetaDataKey to json string yourself, and also deserialize from string.
Create a JsonConverter for dictionary and use it in your JsonConvert.SerializeObject and JsonConvert.DeserializeObject methods.
The simplest thing you can do is to convert the dictinary to a List<KeyValuePair<MetaData,User>> this is easy as _dictionary.ToList()
So for serializing:
string json = JsonConvert.SerializeObject(_dictionary.ToList());
And for deserialize:
_dictionary =
JsonConvert.DeserializeObject<List<KeyValuePair<MetaDataKey, User>>>(json)
.ToDictionary(kv => kv.Key, kv => kv.Value);
For most cases I would choose option 3
Try to use JsonProperty attribute like the following:
internal class User
{
[JsonProperty("UserName ")]
public string UserName { get; set; }
[JsonProperty("UserPassword")]
public string UserPassword { get; set; }
[JsonProperty("Accounts ")]
public List<Account> Accounts { get; set; }
}

How do I deserialize a Json object?

This is the code I use to deserialize JSON.But when I try writing it in console, it says "System.Collections.Generic.Dictionary`2[System.String, System.Object]"
System.Net.WebClient wc = new System.Net.WebClient();
string Jayson = wc.DownloadString("http://api.urbandictionary.com/v0/define?term=api");
object obj = JsonHelper.Deserialize(Jayson);
Dictionary<string, object> values =
JsonConvert.DeserializeObject<Dictionary<string, object>>(Jayson);
Console.WriteLine(values);
How do I deserialize it and extract only the "definition" from the JSON?
You can create some concrete types to map to and deserialize using those rather than more generic types, for example:
public class Result
{
[JsonProperty("definition")]
public string Definition { get; set; }
[JsonProperty("author")]
public string Author { get; set; }
[JsonProperty("permalink")]
public string PermaLink { get; set; }
}
public class Results
{
[JsonProperty("list")]
public List<Result> List { get; set; }
[JsonProperty("tags")]
public List<string> Tags { get; set; }
}
Then:
var results = JsonConvert.DeserializeObject<Results>(json);
You can then iterate the definitions:
foreach(var result in results.List)
Console.WriteLine(result.Definition);
Json.NET will ignore the other properties it can't map so you can add/remove them as needed.
You're getting "System.Collections.Generic.Dictionary`2[System.String, System.Object]" because Console.WriteLine can only write strings and it doesn't know how to turn a dictionary into a string.
To print all the entries, loop over the collection and print each entry:
System.Net.WebClient wc = new System.Net.WebClient();
string Jayson = wc.DownloadString("http://api.urbandictionary.com/v0/define?term=api");
object obj = JsonHelper.Deserialize(Jayson);
Dictionary<string, object> values =
JsonConvert.DeserializeObject<Dictionary<string, object>>(Jayson);
foreach(var entry in values)
{
Console.WriteLine($"{entry.Key} : {entry.Value}");
}
Just parse your json string to a JObject and then get the "defenition" property from it
jObj = JObject.Parse("yourJsonString");
string defenition = jo["definition"];

Turn string into json C#

I have this sample code that i am working with. The json is a result of the http post.
var json = #"{'user': {
'country':'US',
'email':'testapi#example.com',
'first_name':'Test',
'last_name':'API',
'phone':null,
'zip':null,
'login_url':'https://new.site.com/xlogin/12325/abd9832cd92'
}
}";
var jsonSerializer = new JavaScriptSerializer();
var itemsList = (IDictionary<string, object>)jsonSerializer.DeserializeObject(json);
var url = itemsList["user.login_url"];
On itemsList["user.login_url"] i am getting the following error:
The given key was not present in the dictionary.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
Source Error:
Line 545: var jsonSerializer = new JavaScriptSerializer();
Line 546: var itemsList = (IDictionary<string, object>)jsonSerializer.DeserializeObject(json);
Line 547: var url = itemsList["user.login_url"];
Line 548: }
Line 549:
Am i doing something wrong here? How should i access the first name, last name and url etc from this object?
Alternately, how can i tie this result to a class that has following properties? I just need a pointer to a good resource.
public class User
{
public string Country { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public string Zip { get; set; }
public string LoginUrl { get; set; }
}
Thanks.
Well I really don't understand why u are using IDictionary to parse json object.
Use Newtonsoft.Json instead of jsonSerializer much more essay to use.
Go on http://json2csharp.com/ and generate your class to define you json (copy json and result is C# class).
Now tie your json to new RootObject not user:
using System;
using Newtonsoft.Json;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var json = #"{'user': {
'country':'US',
'email':'testapi#example.com',
'first_name':'Test',
'last_name':'API',
'phone':null,
'zip':null,
'login_url':'https://new.site.com/xlogin/12325/abd9832cd92'
}
}";
RootObject userObj = JsonConvert.DeserializeObject<RootObject>(json.ToString());
}
}
//generated with http://json2csharp.com/
public class User
{
public string country { get; set; }
public string email { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public object phone { get; set; }
public object zip { get; set; }
public string login_url { get; set; }
}
public class RootObject
{
public User user { get; set; }
}
}
"user.login_url" is the property path you'd expect to use in JavaScript ... try accessing the dictionary keys instead
var user = itemsList["user"] as IDictionary<string,object>;
var url = user["login_url"] as string;
itemsList["user"] contains a second Dictionary. So you can navigate down to the login_url variable using
var user = (IDictionary<string, object>)itemsList["user"];
var login_url = user["login_url"];
Try using http://json.net/ it will give you a Dictionary with the types you want..

Store a JSON string in C# and then access individual parts of it

I am pulling some JSON from an API. It comes in this format:
{"yourname": {
"id": 42728521,
"name": "Your Name",
"profileIconId": 27,
"revisionDate": 1397930999000,
"summonerLevel": 1
}}
However, that is stored as:
"{\"yourname\":{\"id\":42728521,\"name\":\"Your Name\",\"profileIconId\":27,\"summonerLevel\":1,\"revisionDate\":1397930999000}}"
Inside the string.
I want to be able to call summonerLevel and for it to return the correct value.
I've been trying this:
using (var client = new WebClient())
{
api_return = client.DownloadString(api_call_key);
}
var foo = JsonConvert.DeserializeObject<Summoner>(api_return);
Console.WriteLine(Summoner.id);
Console.WriteLine(Summoner.name);
Console.WriteLine(Summoner.summonerLevel);
string id_ = foo.ToString();
Console.WriteLine(id_);
Console.ReadKey();
}
public class Summoner
{
public static int id { get; set; }
public static string name { get; set; }
public static int summonerLevel { get; set; }
}
However, that just prints out:
0
nothing
0
You have two issues here, which are both preventing you from getting the data from the JSON.
The first issue is that the properties of your Summoner class should not be static, as Vikas pointed out. Define your class like this:
public class Summoner
{
public int id { get; set; }
public string name { get; set; }
public int summonerLevel { get; set; }
}
The second issue is that your JSON structure doesn't match what you're deserializing into. The id, name and summonerLevel properties are not at the root level of the JSON, they are one level further down, inside another object. So, you'll need to deserialize into some class that "wraps" your Summoner. If the yourname property in the JSON were a fixed value, you could define a Wrapper class like this to deserialize into:
public class Wrapper
{
[JsonProperty("yourname")]
public Summoner Summoner { get; set; }
}
However, since the yourname property in the JSON is likely not a fixed value (it could change for different summoners), I would recommend deserializing into a Dictionary<string, Summoner> like this instead:
var dict = JsonConvert.DeserializeObject<Dictionary<string, Summoner>>(json);
From there, you can either loop through the dictionary key-value pairs, or, if you're only expecting one, you can use First() to get it.
var summoner = dict.First().Value;
Here is a full demo:
string json = #"{""yourname"": {
""id"": 42728521,
""name"": ""Your Name"",
""profileIconId"": 27,
""revisionDate"": 1397930999000,
""summonerLevel"": 1
}}";
var dict = JsonConvert.DeserializeObject<Dictionary<string, Summoner>>(json);
var summoner = dict.First().Value;
Console.WriteLine(summoner.id);
Console.WriteLine(summoner.name);
Console.WriteLine(summoner.summonerLevel);
Output:
42728521
Your Name
1
Properties in Summoner class should not be static
using (var client = new WebClient())
{
api_return = client.DownloadString(api_call_key);
}
var foo = JsonConvert.DeserializeObject<Summoner>(api_return);
Console.WriteLine(foo.id);
Console.WriteLine(foo.name);
Console.WriteLine(foo.summonerLevel);
..............
}
public class Summoner
{
public int id { get; set; }
public string name { get; set; }
public int summonerLevel { get; set; }
}

Json string deserialized to array list of objects

Please help!
Getting this error on Deserializing:
Cannot convert object of type 'System.String' to type
'System.Collections.Generic.List'
JSON string from client:
"\"[{\\"id\\":\\"18_0_2_0\\",\\"ans\\":\\"You can enter free
text in place of
*\\"},{\\"id\\":\\"23_1_3_1\\",\\"ans\\":\\"The refresh button\\"},{\\"id\\":\\"11_2_1_2\\",\\"ans\\":\\"False\\"}]\""
Edit: Unescaped (see comments):
[{"id":"18_0_2_0","ans":"You can enter free text in place of *"},{"id":"11_2_1_2","ans":"False"}]
JavaScriptSerializer serializer = new JavaScriptSerializer();
List<RawAnswer> ListAnswers = serializer.Deserialize<List<RawAnswer>>(str);
[Serializable]
public class RawAnswer
{
public string QuestionID { get; set; }
public string Answer { get; set; }
public RawAnswer() { }
}
public class AnswerList
{
public List<RawAnswer> RawAnswer { get; set; }
}
Your original json string(before aKzenT's edit) was double escaped and I used var str2 = Regex.Unescape(str); to get the actual string .
public class RawAnswer
{
public string id { get; set; }
public string ans { get; set; }
}
And no need for AnswerList
Now your code can work
JavaScriptSerializer serializer = new JavaScriptSerializer();
List<RawAnswer> ListAnswers = serializer.Deserialize<List<RawAnswer>>(str);
The JSON string you receive from the client is itself a string containing the actual JSON string you're looking for. Either fix the client to send you a correct string, or first deserialize this result into a String, and then deserialize that into a List<RawAnswer>.

Categories

Resources