I get this response string from the Bitly api:
{ "status_code": 200,
"status_txt": "OK",
"data":
{ "long_url": "http:\/\/amazon.de\/",
"url": "http:\/\/amzn.to\/1mP2o58",
"hash": "1mP2o58",
"global_hash": "OjQAE",
"new_hash": 0
}
}
How do I convert this string to a dictionary and how do I access the value for the key "url" (without all the \)
This isn't just some ordinary string. This is a data structure in JSON format, a common and well-established format, originally used in Javascript but now rather common as a data transfer mechanism between services and clients.
Rather than reinventing the wheel and parsing the JSON yourself, I suggest you use an existing JSON library for C#, such as JSON.NET, which will eat up that string and parse it into .NET objects for you.
Here's a code sample, taken from JSON.NET's documentation, showing its usage:
string json = #"{
'href': '/account/login.aspx',
'target': '_blank'
}";
Dictionary<string, string> htmlAttributes =
JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Console.WriteLine(htmlAttributes["href"]);
// /account/login.aspx
Console.WriteLine(htmlAttributes["target"]);
// _blank
If you add a package like Newtonsoft's Json to your project, you can deserialize the Json in to an anonymous type. You can then fetch the url from that. This is available via NuGet within Visual Studio and provides support for async or sync serialization/deserialization.
public string GetUrl(string bitlyResponse)
{
var responseObject = new
{
data = new { url = string.Empty },
};
responseObject = JsonConvert.DeserializeAnonymousType(bitlyResponse, responseObject);
return responseObject.data.url;
}
I'd use JSON.NET.
http://james.newtonking.com/json
MIT License which means if you're doing anything commercial you are good.
I don't think you would want to go straight to a Dictionary, because there is some stuff there that isn't a one to one relationship. So you could make a class like the following.
public class BitlyData
{
public string LongUrl{ get; set; }
public string Url { get; set; }
public string Hash { get; set; }
public string GlobalHash { get; set; }
public string NewHash { get; set; }
}
You could then use Json.NET to turn that String into an JObject. So we'll call your string bitlyString.
JObject bitlyObject = JObject.Parse(bitlyString);
Now we have that all that is left to do is access the data.
BitlyData theData = JsonConvert.DeserializeObject<BitlyData>(bitlyObject["data"]);
Then you can access the url (and any other pieces) using the getters.
Of course you could make it even better by having class that handles the other bits as well so you just do one serialisation.
1)Add these classes to your project
public class Rootobject
{
public int status_code { get; set; }
public string status_txt { get; set; }
public Data data { get; set; }
}
public class Data
{
public string long_url { get; set; }
public string url { get; set; }
public string hash { get; set; }
public string global_hash { get; set; }
public int new_hash { get; set; }
}
2)Add a reference to JSON.NET
3)
string jsonString= "YOUR JSON STRING";
Rootobject weps = JsonConvert.DeserializeObject<Rootobject>(jsonString);
Console.WriteLine(weps.status_code);
if (weps.data != null)
{
Console.WriteLine(weps.data.url);
Console.WriteLine(weps.data.global_hash);
//...
}
Related
I got this strange API response from one external service:
{emplooye: "Michael",age:"25",attachments:[{idAttachment: "23",attachmentPath:"C://Users/1"},{idAttachment: "24",attachmentPath:"C://Users/2"}]},{emplooye: "John",age:"30",attachments:{idAttachment: "25",attachmentPath:"C://Users/3"}}
Has anyone ever faced a situation where sometimes the "Attachment" property can be an array, sometimes it can be an object? I created a class to manipulate the data, but when I find an object, the code breaks.
I'm doing this in C#.
Class Used
public class Attachments
{
public string idAttachment{ get; set; }
public string attachmentPath{ get; set; }
}
public class Root
{
public string emplooye {get; set;}
public string age {get;set}
public List<Attachments> attachments { get; set; } = new List<Attachments>();
}
your json is not even close to json, should be something like this
var json = "[{\"emplooye\":\"Michael\",\"age\":\"25\",\"attachments\":[{\"idAttachment\":\"23\",\"attachmentPath\":\"C://Users/1\"},{\"idAttachment\":\"24\",\"attachmentPath\":\"C://Users/2\"}]},{\"emplooye\":\"John\",\"age\":\"30\",\"attachments\":{\"idAttachment\":\"25\",\"attachmentPath\":\"C://Users/3\"}}]";
Using Newtonsoft.Json you can create a JsonConstructor
using Newtonsoft.Json;
List<Data> data= JsonConvert.DeserializeObject<List<Data>>(json);
public class Data
{
public string emplooye { get; set; }
public string age { get; set; }
public List<Attachments> attachments { get; set; }
[JsonConstructor]
public Data(JToken attachments)
{
if (attachments.Type.ToString() == "Array")
this.attachments = attachments.ToObject<List<Attachments>>();
else
this.attachments = new List<Attachments> { attachments.ToObject<Attachments>() };
}
public Data() {}
}
public class Attachments
{
public string idAttachment { get; set; }
public string attachmentPath { get; set; }
}
You can use Newtonsoft to parse to a JToken which will handle the typing for you, but with the downside of not having a stable and predictable class to deserialize to automatically
Then, you would want to check its type, which returns a JTokenType enum
Once you know what the underlying types are, marshal the data into your DTO classes
JToken responseJT = JToken.Parse(json); //json string
if (responseJT.Type == JTokenType.Array)
//its an array, handle as needed ...
else if (responseJT.Type == JTokenType.Object)
//its an object, handle as needed ...
Personally, I would keep the attachments property as a List<Attachments> and if the JToken has a JSON object I would just set it as the [0] index of that property. This way things stay consistent and you can use LINQ on that property with ease
I am retrieving data from office365 api. The response is in JSON format. I want to get data like Id, DisplayName etc. into variables but not getting the right way to do it. Following this link. I'm new to API and JSON. Will Appreciate pointers as well towards best learning links.Sample JSON below for listing sub folders of Inbox folder.
Response JSON data.
{"#odata.context":"https://outlook.office365.com/api/v1.0/$metadata#Me/Folders('Inbox')/ChildFolders","value":
[
{"#odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user#demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmsdfsdfdDSFSDFDFDF=')",
"Id":"AAMkADBjMdfgdfgDFGDFGDFGdfGDFGDFGDFGGDzrACAAB4xqMmAAA=",
"DisplayName":"SampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":8,"TotalItemCount":94},
{"#odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user#demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEasdasdasdASDASDASDASDSADDASDASDAB4xqMnAAA=')",
"Id":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmOGZkNGRhZmIzNQAuAasdASDASDASDASEDASDASDxSEHjzrACAAB4xqMnAAA=",
"DisplayName":"AnotherSampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":21,"TotalItemCount":75}
]
}
The C# code using to parse JSON and find the required data.
HttpResponseMessage response = httpClient.SendAsync(request).Result;
if (!response.IsSuccessStatusCode)
throw new WebException(response.StatusCode.ToString() + ": " + response.ReasonPhrase);
string content = response.Content.ReadAsStringAsync().Result;
JObject jResult = JObject.Parse(content);
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
var folderName = results.Id;
var folderId = results.Name;
//Attempt two - [Not working - Throwing exception -
//Object reference not set to an instance of an object.]
var folderID = (string)jResult["odata.context"]["odata.id"][0]["Id"];
First create a class for your json object
public class RootObject
{
[JsonProperty(PropertyName = "#odata.context")]
public string context { get; set; }
public List<Value> value { get; set; }
}
public class Value
{
[JsonProperty(PropertyName = "#odata.id")]
public string dataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
Then Json Convert the Json string to your RootObject if your are using Newtonsoft Json then Deserilaze by using
RootObject shortiee = JsonConvert.DeserializeObject<RootObject>("Your Json String");
private List<string> GetDisplayNames(JObject content)
{
var obj = Json.Parse(content);
var values = obj["value"].ToList();
var displayNames = new List<string>();
foreach (var value in values)
{
displayNames .Add(system["DisplayName"].ToString());
}
return displayNames;
}
This would return the names, for example, and you could do this for each value you need to retrieve. However, this does not require you to serialize/deserialize the json object before using it. It works, but is most likely not best practice.
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
Side note: There is no key called "odata.error" in your JSON data. So you're effectively calling something which will return null.
One of the ways to deserialise JSON is to create model classes for the objects you want to process and deserialise into them directly, eg. JsonConvert.DeserializeObject<Folder>(content). As you are talking to an Office365 API, you find documentation and examples here on how they are defined.
Taken your folder response as an example, your model for a single Folder could look like this:
public class Folder
{
[JsonProperty(PropertyName = "#odata.id")]
public string OdataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
Note1: in your example, you get a response with list of folders, so have to adjust this accordingly.
Note2: you can use JsonProperty to define a mapping between a JSON property/key and a C# property as shwon for #odata.id.
However, you can also use the Outlook Client Library which would make it mostly unnecessary to deal with JSON data directly (which seems preferable, unless you have a very specific reason to deal with JSON directly).
I retrieve an information from Steam about a specific game. I provide an application url: http://store.steampowered.com/app/57690/ and get a JSON response like:
{
"57690":{ // this is dynamically got from application id above ^
"success":true
"data": { }
}
}
I have an object, SteamData
public bool success { get; set; }
public InternalData data { get; set; }
and InternalData
public string name { get; set; }
public string about_the_game { get; set; }
public string supported_languages { get; set; }
...
I tried to deserialize above json to SteamData using:
SteamData data = JsonConvert.DeserializeObject<SteamData>( thatJsonAbove );
It's not working because there exists a root which is an application id...
How to deserialize only what is inside root (in this example, what's inside "57690") ?
In case of using Newtonsoft JSON library you may try this:
JObject gameInfo = JObject.Parse(json);
SteamData data= gameInfo.SelectToken("57690", false).ToObject<SteamData>();
Since you know game's id - you can easily use this approach.
I'm facing some problems with the read of a JSON file, which is this one:
{
"giocatori": [
{
"Giocatore": "124",
"Cognome": "DE SANCTIS",
"Ruolo": "P",
"Squadra": "ROM"
},
{
"Giocatore": "140",
"Cognome": "MIRANTE",
"Ruolo": "P",
"Squadra": "PAR"
},
{
"Giocatore": "156",
"Cognome": "SKORUPSKI",
"Ruolo": "P",
"Squadra": "ROM"
}
],
"success": 1
}
What I want to get from this PHP is an List, where the Player's class with this attributes;
public string Giocatore;
public string Cognome;
public string Ruolo;
public string Squadra;
I don't know why, but I face some problems with the Microsoft.Json library, in particular with Json.DeserializeObject> method, which is not able to read that web page. Can you provide some hint how to obtain a List in C# of Player ? Thank you so much for your support !
Go to http://json2csharp.com/, post your JSON there, and get the following classes:
public class Giocatori
{
public string Giocatore { get; set; }
public string Cognome { get; set; }
public string Ruolo { get; set; }
public string Squadra { get; set; }
}
public class RootObject
{
public List<Giocatori> giocatori { get; set; }
public int success { get; set; }
}
To deserialize your JSON string with JavaScriptSerializer, do:
var root = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(jsonString);
var list = root.giocatori;
To deserialize your JSON string with Json.NET, a widely used, free, open source JSON serializer, download and install it according to the instructions on the home page and do:
var root = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsonString);
var list = root.giocatori;
I am having issues with understanding how to make this happen.
Basically we have an API, the user sends a JSON of the format:
{
"Profile":[
{
"Name":"Joe",
"Last":"Doe",
"Client":{
"ClientId":"1",
"Product":"Apple",
"Message":"Peter likes apples"
},
"Date":"2012-02-14"
}
]
}
I have a class called Profile with parameters Name, Last, and an object as one of its members called Client as well as property Date.
Something like this:
public class Profile {
public string Name {get; set;}
public string Last {get; set;}
public Client client {get; set;}
public DateTime dDate {get; set;}
}
So basically, I am not sure how to grab the JSON and then map it to my object.
Any help with "helping" me understand would be much appreciated.
You can use Json.NET to deserialize your json string as (with some modifications to your classes)
var yourObject = JsonConvert.DeserializeObject<Root>(jsonstring);
public class Root
{
public Profile[] Profile;
}
public class Profile
{
public string Name { get; set; }
public string Last { get; set; }
public Client Client { get; set; }
public DateTime Date { get; set; }
}
public class Client
{
public int ClientId;
public string Product;
public string Message;
}
You can use a JSON library for this, for example Newtonsoft.Json which is free. It will map json to your types automatically.
Sample:
public static T Deserialize<T>(string json)
{
Newtonsoft.Json.JsonSerializer s = new JsonSerializer();
return s.Deserialize<T>(new JsonTextReader(new StringReader(json)));
}
There is also a NuGet package available.
Easiest way I know is to use JSON.Net by newtonsoft.
To make it easier to understand, I always make matching classes in C# with the same name.
Then its easier to deserialize it.
As an example, if it is an array of objects in js, it will map to a list of object with the same names in C#.
As for the date time, its a bit tricky.
Id do the client side validation and Datetime.tryParse in the serverside, itll take care of the dashes or slashes.
var serializer = new JavaScriptSerializer();
List<abc> abcList = serializer.Deserialize<List<abc>>(PassedInJsonString);
I know this is a long time question, but I would like to add one more option, which does not use third party libraries, and only uses stock .Net libraries, and is available from .Net Core 3.1 onwards.
First of all, I leave a link to the official Microsoft documentation (where you will find examples on how to serialize and deserialize json strings): https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to
Let's build on your example. We have our starting json string:
{
"Profile":[
{
"Name":"Joe",
"Last":"Doe",
"Client":{
"ClientId":"1",
"Product":"Apple",
"Message":"Peter likes apples"
},
"Date":"2012-02-14"
}
]
}
If we build a data structure that can hold that definition, it would be something like:
public class Root
{
public List<Profile> Profile { get; set; }
}
public class Profile
{
public string Name { get; set; }
public string Last { get; set; }
public Client Client { get; set; }
public string Date { get; set; }
}
public class Client
{
public string ClientId { get; set; }
public string Product { get; set; }
public string Message { get; set; }
}
Now, and finally the answer to how to deserialize a json string into a particular object without third party libraries:
Root root = JsonSerializer.Deserialize<Root>(json);
Where json is the variable that contains your json string.
I add another link of interest, the official documentation of the Deserialize(...) method: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializer.deserialize
Something that is really useful is the exception that can be thrown, JsonException: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonexception
DataContractJsonSerializer does the job, but it uses more sophisticated format for DateTime serialization.