I am trying to parse a JSON response from a SharePoint list and parse certain nodes to a list. There can be multiple records. I am using Newsoft Json to deserialize the response. Everything works expect the foreach loop I created iterates through the results one time. Also in the foreach loop the items variable has data as the results variable.
Here is the code:
static List<string> get_json_unsubscribe()
{
int counter = 0;
List<string> list_of_json_users = new List<string>();
String url = "http://server/site/_api/lists/getbytitle('listname')"
HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create(url);
endpointRequest.Credentials = CredentialCache.DefaultCredentials;
endpointRequest.Method = "GET";
endpointRequest.Accept = "application/json;odata=verbose";
HttpWebResponse endpointResponse = (HttpWebResponse)endpointRequest.GetResponse();
Stream receiveStream = endpointResponse.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
dynamic results = JsonConvert.DeserializeObject<dynamic>(readStream.ReadToEnd());
foreach (var item in results)
{
string userid= results.d.results[counter].userid
list_of_json_users.Add(userid);
counter++;
}
return list_of_json_users;
}
The endpoint:
http://server/site/_api/lists/getbytitle('<listtitle>')
returns List resource properties, you probably want this endpoint:
http://server/site/_api/lists/getbytitle('<listtitle>')/items
to return list data (ListItemCollection resource)
To deserialize your JSON you could introduce a model:
public class UserInfo
{
[JsonProperty("AuthorId")]
public string AuthorId { get; set; }
}
public class UserInfoResult
{
[JsonProperty("results")]
public List<UserInfo> UserInfoCollection { get; set; }
}
public class UserInfoResultRoot
{
[JsonProperty("d")]
public UserInfoResult Result { get; set; }
}
Note: in the provided example AuthorId property of ListItem
resource is marked for deserialization
In that case deserializing of list items:
dynamic results = JsonConvert.DeserializeObject<dynamic>(readStream.ReadToEnd());
foreach (var item in results)
{
string userid= results.d.results[counter].userid
list_of_json_users.Add(userid);
counter++;
}
could be replaced with:
var json = readStream.ReadToEnd();
var data = JsonConvert.DeserializeObject<UserInfoResultRoot>(json);
list_of_json_userscould be initialized like this:
list_of_json_users = data.Result.UserInfoCollection.Select(ui => ui.AuthorId).ToList();
Related
I did a POST request code pointing to an API to do an automatic exchange program.
Here is the code:
string webAddr = "https://shapeshift.io/shift";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{ \"withdrawal\" : \"***ADDRESS WITH LETTER AND NUMBER***\", \"pair\" : \"eth_xmr\" }";
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
Console.WriteLine(responseText);
}
And after executing the code, I'm getting this in the console
{"orderId":"1f90346c-c6d4-4d89-a24c-78b2bbdb6292","deposit":"0x534aa684274b4711f65b2d0e2e403cb169201255","depositType":"ETH","withdrawal":"***ADDRESS WITH LETTER AND NUMBER***","withdrawalType":"XMR"
Now, I want to put the address from deposit that I'm getting from the API into a string variable. I tried some code but I can't make it working. So how can I put this address in a string variable ?
You could deserialize the response and get from there that you want. In order to do so you could define a class, let's name it ApiResponse:
public class ApiResponse
{
[JsonProperty("orderId")]
public string orderId { get; set; }
[JsonProperty("deposit")]
public string deposit { get; set; }
[JsonProperty("depositType")]
public string depositType { get; set; }
[JsonProperty("withdrawal")]
public string withdrawal { get; set; }
[JsonProperty("withdrawalType")]
public string withdrawalType { get; set; }
}
and then after
var responseText = streamReader.ReadToEnd();
make the deserialization:
var apiResponse = JsonConvert.DeserializeObject<ApiResponse>(responseText);
I have used the Json.NET library. So if you haven't isntall it, you should do so or you could make use of another library and change correspondingly the above code.
I need to write the titles of the countries from VK API to a list from the following link.
I have written some code:
public class GettingCountry
{
public async Task<string> FetchAsync(string url)
{
string jsonString;
using (var httpClient = new System.Net.Http.HttpClient())
{
var stream = await httpClient.GetStreamAsync(url);
StreamReader reader = new StreamReader(stream);
jsonString = reader.ReadToEnd();
}
var readJson = JObject.Parse(jsonString);
string countryName = readJson["response"]["items"].ToString();
var deserialized = JsonConvert.DeserializeObject<RootObject>(jsonString);
return jsonString;
}
}
public class Item
{
public int id { get; set; }
public string title { get; set; }
}
public class Response
{
public int count { get; set; }
public List<Item> items { get; set; }
}
public class RootObject
{
public Response response { get; set; }
}
}
I put a breakpoint and got in string countryName only this:
As you can see the VK API returns you an array of objects.
Your jsonString contains full response string. Now, jsonString["response"]["items"] contains an array of items.
First you need to parse the array and then parse each item, like this:
var readJson = JObject.Parse(jsonString);
JArray countries = JArray.Parse(readJson["response"]["items"]);
var Response listOfCountries = new Response();
foreach (var country in countries) {
Item currentCountry = new Item();
currentCountry.id = country.id;
currentCountry.title = country.title;
listOfCountries.items.Add(currentCountry);
}
listOfCountries.count = listOfCountries.items.Count;
From the code perspective, I would recommend giving proper names to variables, classes, and types to improve code readability and cleanliness. On top of it, I don't really see a point in having a separate Response class. For example, you could rename your Item class and call it Country. All you need to have is a list of countries then. Also, because you're using async method, you want to do the processing of the return within your using for the HttpClient - if you don't the client might be disposed too soon and you might start hitting very weird bugs. Like this:
public class VkCountry
{
public int Id { get; }
public string Title { get; }
public VkCountry(int countryId, string countryTitle) {
this.Id = countryId;
this.Title = countryTitle;
}
}
public async Task<List<VkCountry>> FetchAsync(string url)
{
string jsonString;
using (var httpClient = new System.Net.Http.HttpClient())
{
var stream = await httpClient.GetStreamAsync(url);
StreamReader reader = new StreamReader(stream);
jsonString = reader.ReadToEnd();
var listOfCountries = new List<VkCountry>();
var responseCountries = JArray.Parse(JObject.Parse(jsonString)["response"]["items"].ToString());
foreach (var countryInResponse in responseCountries) {
var vkCountry = new VkCountry((int)countryInResponse["id"], (string)countryInResponse["title"]);
listOfCountries.Add(vkCountry);
}
return listOfCountries;
}
}
You might notice that I've made VkContry implementation immutable, the properties are read-only and can be set using the constructor only. I'd recommend using immutable objects when you are consuming relatively static third-party APIs (list of countries is definitely static, unless some kind of application logic will require you to update the name of the country).
Obviously, you might want to add nullability checks and different validations.
I can explain this question better in terms of code and example. This is my code so far:
url = "x";
// create the request
req = WebRequest.CreateHttp(url);
req.ClientCertificates.Add(Program.GetCert(thumbprint));
result = (HttpWebResponse)req.GetResponse();
using (Stream data = result.GetResponseStream())
{
if (data != null)
{
TextReader tr = new StreamReader(data);
json = tr.ReadToEnd();
}
}
System.Diagnostics.Debug.WriteLine(json);
This is the output of the code:
{ "field1":"blah","field2":[
{
"Id":"1","Name":"Jon"
},{
"Id":"2","Name":"Mark"}] }
What I want to do-->
Access field2 of that json and iterate through ids and names (I don't care about field1 at all). How can I do that? Has this got anything to do with serialization?
one possible solution is -
var o = (JArray)(JObject.Parse(json)["field2"]);
foreach (JToken token in o)
{
Console.WriteLine(token["Id"]);
Console.WriteLine(token["Name"]);
}
Alternatively, you could create strongly typed C# objects and access them as a list -
static void Main(string[] args)
{
var o = JsonConvert.DeserializeObject<RootObject>(json).field2;// list - count = 2
}
public class Field2
{
public string Id { get; set; }
public string Name { get; set; }
}
public class RootObject
{
public string field1 { get; set; }
public List<Field2> field2 { get; set; }
}
Use the DataContractJsonSerializer Class with suitable DataContract classes (Using Data Contracts), to deserialize your JSON data to objects.
Then you can iterate your way through the data.
First install Json.NET and try something like:
dynamic stuff = JObject.Parse(json);
var field2 = (JArray)stuff["field2"];
var field2Dict = field2.ToDictionary(k => (string)k["Id"], x => (string)x["Name"]);
foreach (var item in field2Dict)
{
System.Diagnostics.Debug.WriteLine("Id: {0} Nam: {1}", item.Key, item.Value);
}
here am facing little bit problem while deserializing json string to list
json string : Result of restful service
"\"{\\"UName\\":\\"prasad\\",\\"LastName\\":\\"k\\",\\"FirstName\\":\\"sai\\"}\""
and i want to convert this json string to genric list
my list :
public class _TempUser
{
public string UName
{
get;
set;
}
public string LastName
{
get;
set;
}
public string FirstName
{
get;
set;
}
}
Error is
Error converting value "{"UName":"prasad","LastName":"k","FirstName":"sai"}" to type 'System.Collections.Generic.List`1[loginServices.Login_Service+_TempUser]'. Path '', line 1, position 70.
code : for calling restful service
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http ://IpAddress:Post/Login/RestServiceName.svc/RestMethoName");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json =JsonConvert.SerializeObject(Req);
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
string result = streamReader.ReadToEnd();
List<_TempUser> List = new List<_TempUser>();
List = JsonConvert.DeserializeObject<List<_TempUser>>result
}
}
any modifications or suggestions plz
First your json string must be like this:
"{\"UName\":\"prasad\",\"LastName\":\"k\",\"FirstName\":\"sai\"}"
NOT
"\"{\\"UName\\":\\"prasad\\",\\"LastName\\":\\"k\\",\\"FirstName\\":\\"sai\\"}\""
Then you can parse it using:
string entry = "{\"UName\":\"prasad\",\"LastName\":\"k\",\"FirstName\":\"sai\"}";
var parsedObject = JsonConvert.DeserializeObject<JObject>(entry);
foreach (var dataset in parsedObject.Properties())
{
Console.WriteLine(dataset.Name);
}
I am using Newtonsoft.Json and Newtonsoft.Json.Linq for the parsing.
I'm having trouble deserializing an array in .NET MVC3, any help would be appreciated.
Here's the code snippet:
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
string jsonData = reader.ReadToEnd();
result = (BigCommerceOrderProducts)jsSerializer.Deserialize<BigCommerceOrderProducts>(jsonData);
}
Here's the subset of the data string returned by JSON as jsonData. I've remove extra fields.
"[
{\"id\":33,\"order_id\":230025,...},
{\"id\":34,\"order_id\":230025,...}
]"
Here are the objects:
[Serializable]
public class BigCommerceOrderProducts {
public List<BigCommerceOrderProduct> Data { get; set; }
}
[Serializable]
public class BigCommerceOrderProduct {
public int Id { get; set; }
public int Order_id { get; set; }
...
}
I'm getting this error:
"Type 'Pxo.Models.BigCommerce.BigCommerceOrderProducts' is not supported for deserialization of an array.
Any ideas?
You should deserialize your json string to type List<BigCommerceOrderProduct>. No need for BigCommerceOrderProducts class
var myobj = jsSerializer.Deserialize<List<BigCommerceOrderProduct>>(jsonData);
This little proggy works fine for me. Could be something unexpected in the response stream.
The json output is: {"Data":[{"Id":33,"Order_id":230025},{"Id":34,"Order_id":230025}]}
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
BigCommerceOrderProducts a = new BigCommerceOrderProducts();
a.Data = new List<BigCommerceOrderProduct>();
BigCommerceOrderProduct b = new BigCommerceOrderProduct();
b.Id = 33;
b.Order_id = 230025;
a.Data.Add(b);
b = new BigCommerceOrderProduct();
b.Id = 34;
b.Order_id = 230025;
a.Data.Add(b);
string x = jsSerializer.Serialize(a);
Console.WriteLine(x);
a = jsSerializer.Deserialize<BigCommerceOrderProducts>(x);
Console.WriteLine(a.Data[0].Order_id);
Console.ReadLine();