Convert Json Singleton into List Phone 81 UAP - c#

I am using http client to return a json response from a webservice. The example I am following here is from code project tutorial. However its example only returns into a var, it was created for the method to be called on screen I am changing it to be called from within a class. I have removed the webservice for security.
My Main question is how would I change this function to return a List of cinemas instead of the var variable I have a class created as such. I tried changing var into List but i noticed json.net handles this list so I need return the var as a known object instead I think?.
public class City
{
public string id { get; set; }
public string timing_title { get; set; }
}
public class Citys
{
public List<City> city { get; set; }
}
I just don't know what to do to convert this so it returns a list of citys for me to use in function.
This is a list of example json data returned.
{"city":[{"id":"5521","timing_title":"Lahore"},{"id":"5517","timing_title":"Karachi"},{"id":"5538","timing_title":"Islamabad"},{"id":"5535","timing_title":"Rawalpindi"},{"id":"5518","timing_title":"Hyderabad"},{"id":"5512","timing_title":"Faisalabad"},{"id":"8028","timing_title":"Gujranwala"},{"id":"8027","timing_title":"Gujrat"}]}
public async void GetCinemasList()
{
try
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("webserviceurl");
var url = "index.php/webservice/upcoming_movie";
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var data = response.Content.ReadAsStringAsync();
var cityData = JsonConvert.DeserializeObject<City>(data.Result.ToString());
}
}
}
catch (Exception ex)
{
// MessageBox.Show("Some Error Occured");
}
}

You have a string holding a JSON value.
You can parse and iterate through JSON values like this:
var data = "{\"city\":[{\"id\":\"5521\",\"timing_title\":\"Lahore\"},{\"id\":\"5517\",\"timing_title\":\"Karachi\"},{\"id\":\"5538\",\"timing_title\":\"Islamabad\"},{\"id\":\"5535\",\"timing_title\":\"Rawalpindi\"},{\"id\":\"5518\",\"timing_title\":\"Hyderabad\"},{\"id\":\"5512\",\"timing_title\":\"Faisalabad\"},{\"id\":\"8028\",\"timing_title\":\"Gujranwala\"},{\"id\":\"8027\",\"timing_title\":\"Gujrat\"}]}";
JsonObject rootObject;
if (JsonObject.TryParse(data, out rootObject))
{
JsonArray cityArray = rootObject.GetNamedArray("city");
foreach (var jsonValue in cityArray)
{
JsonObject cityObject = jsonValue.GetObject();
Debug.WriteLine(cityObject.GetNamedString("timing_title"));
}
}
else
{
// Invalid JSON data.
}
Output:
Lahore
Karachi
Islamabad
Rawalpindi
Hyderabad
Faisalabad
Gujranwala
Gujrat

Related

.NET 6 JsonSerializer.Deserialize returns defined array with empty objects

Currently I am trying to deserialize a json string from a http response. I have verified the string returned is valid JSON. When the deserialize function completes I have an array with undefined objects.
public async Task<IEnumerable<MemberRoster>> GetAsync(string groupNumber)
{
var httpClient = _httpClientFactory.CreateClient();
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Add("client_id", Configuration["Microservices:RequestHeaders:client_id"]);
httpClient.DefaultRequestHeaders.Add("client_secret", Configuration["Microservices:RequestHeaders:client_secret"]);
var queryParams = new Dictionary<string, string>()
{
["groupNumber"] = groupNumber
};
var memberUri = QueryHelpers.AddQueryString(Configuration["Microservices:Member"], queryParams);
var response = await httpClient.GetAsync(memberUri).Result.Content.ReadAsStringAsync();
var data = JsonSerializer.Deserialize<IEnumerable<MemberRoster>>(response);
return data;
}
public class MemberRoster
{
[JsonPropertyName("health_id")]
string HealthId { get; set; }
};
JSON in response
I need to add the public accessor to my properties.

UWP Json to C# conversion

I want to serialize some json data I get from the web to classes and use the data, so I went to http://json2csharp.com/ and turned the json as below
json: [{"line_descr":"\u03a0\u0395\u0399\u03a1\u0391\u0399\u0391\u03a3 -
\u0392\u039f\u03a5\u039b\u0391","line_descr_eng":"PEIRAIAS - VOYLA"}]
To this class:
public class RootObject
{
public string line_descr { get; set; }
public string line_descr_eng { get; set; }
}
This is my code:
class LineName
{
public async static Task<RootObject> GetLineName(int linecode)
{
var http = new HttpClient();
var response = await http.GetAsync("http://telematics.oasa.gr/api/?act=getLineName&p1=962");
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject)serializer.ReadObject(ms);
return data;
}
}
[DataContract]
public class RootObject
{
[DataMember]
public string line_descr { get; set; }
[DataMember]
public string line_descr_eng { get; set; }
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
RootObject myLine = await LineName.GetLineName(92);
ResultTextBlock.Text = myLine.line_descr_eng;
}
So when I try to get the data and display it in my textblock I get the error: line_descr_eng is null.
Can someone point where the fault is ? since the line_descr_eng should be
PEIRAIAS - VOYLA but mine is null and after a lot of searching I cant find where the fault is.
Your json is an array, not an object, and you should deserialize it into an array.
public async static Task<RootObject[]> GetLineName(int linecode)
{
var http = new HttpClient();
var response = await http.GetAsync("http://telematics.oasa.gr/api/?act=getLineName&p1=962");
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject[]));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject[])serializer.ReadObject(ms);
return data;
}
//...
var myLines = await LineName.GetLineName(92);
var myLine = myLines.FirstOrDefault();
Also you don't need a memory stream, you can read stream from the http response
var result = await response.Content.ReadAsStreamAsync();
You simple can use the JavaScriptSerializer class instead of DataContractJsonSerializer like this:
Replace:
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject)serializer.ReadObject(ms);
with this:
var ser = new JavaScriptSerializer();
var test = ser.Deserialize<List<RootObject>>(json);
If you cannot find JavaScriptSerializer, then you have to do the simple following steps:
Right click References and do Add Reference, then from Assemblies->Framework select System.Web.Extensions.
Now you should be able to add the following to your class file:
using System.Web.Script.Serialization;
Cited from: https://stackoverflow.com/a/15391388/5056173

Unable to Serialize/Deserialize List<> object into JSON

I am working on 2 web applications; A & B. now i have a shared class named CRUDOutput as follow on both web applications:-
public class CRUDOutput
{
public Operation4 operation { get; set; }
}
public class Operation4
{
public Result result { get; set; }
public string name { get; set; }
}
public class Result
{
public string status { get; set; }
public string message { get; set; }
}
now inside web application A i am returning the following:-
[HttpPost]
public ActionResult CreateResource(CreateResource cr)
{
List<CRUDOutput> co = new List<CRUDOutput>();
co.Add(JsonConvert.DeserializeObject<CRUDOutput>(crudoutput));
co.Add(JsonConvert.DeserializeObject<CRUDOutput>(crudoutput2));
return Json(JsonConvert.SerializeObject(co));
}
now from web application B, i am calling the action method as follow:-
try
{
using (WebClient wc = new WebClient())
{
string url = "https://localhost:44302/" + "Home/CreateResource";
Uri uri = new Uri(url);
wc.Headers.Add(HttpRequestHeader.ContentType, "application/json");
output = wc.UploadString(uri, data);
}
}
catch (WebException e)
{
}
List<CRUDOutput> result = JsonConvert.DeserializeObject<List< CRUDOutput>>(output);
but i will get the following exception when i tried to deserialize the output:-
Error converting value
"[{"operation":{"result":{"status":"Success","message":"Resource has
been added successfully to ......"},"name":"CREATE
RESOURCE"}},{"operation":{"result":{"status":"Failed","message":"Account
addition "},"name":"ADD ACCOUNTS"}}]" to type
'System.Collections.Generic.List`1[S.ViewModels.CRUDOutput]'. Path '',
line 1, position 464.
now the JSON return from web application A will be as follow:-
"\"[{\\\"operation\\\":{\\\"result\\\":{\\\"status\\\":\\\"Success\\\",\\\"message\\\":\\\"Resource 123 rfrf has been added successfully \\\"},\\\"name\\\":\\\"CREATE RESOURCE\\\"}},{\\\"operation\\\":{\\\"result\\\":{\\\"status\\\":\\\"Failed\\\",\\\"message\\\":\\\"Account addition \\\"},\\\"name\\\":\\\"ADD ACCOUNTS\\\"}}]\""
so can anyone advice why i am unable to deserialize to a list of objects?
The output as you've pasted is encoded as JSON twice. Compare the difference between:
"\"[{\\\"operation\\\":{\\\"result\\\":{\\\"status\\\":\\\"Success\\\",\\\"message\\\":\\\"Resource 123 rfrf has been added successfully \\\"},\\\"name\\\":\\\"CREATE RESOURCE\\\"}},{\\\"operation\\\":{\\\"result\\\":{\\\"status\\\":\\\"Failed\\\",\\\"message\\\":\\\"Account addition \\\"},\\\"name\\\":\\\"ADD ACCOUNTS\\\"}}]\""
and
"[{\"operation\":{\"result\":{\"status\":\"Success\",\"message\":\"Resource 123 rfrf has been added successfully \"},\"name\":\"CREATE RESOURCE\"}},{\"operation\":{\"result\":{\"status\":\"Failed\",\"message\":\"Account addition \"},\"name\":\"ADD ACCOUNTS\"}}]"
This happens because you're encoding the result as Json twice. Replace:
return Json(JsonConvert.SerializeObject(result));
with
return Json(result); // This encodes as JSON automatically

Deserialize list of JSON objects

I got a Windows Phone 8.1 app.
I am trying to parse a list of objects returned by my Web API call.
On my server I have this code:
Default.aspx:
[WebMethod]
public static List<Shared.PremisesResponse> GetPremises(string emailaddress)
{
Premises premises = new Premises();
return premises.GetPremises(emailaddress);
}
In that premise object class
public List<Shared.PremisesResponse> GetPremises(string emailAlias)
{
DAL dal = new DAL();
List<Shared.PremisesResponse> premises = new List<Shared.PremisesResponse>();
try
{
DataSet dtMacs = dal.GetMacs(emailAlias);
for (int index = 0; index < dtMacs.Tables[0].Rows.Count; index++)
{
Shared.PremisesResponse itemMAC1 = new Shared.PremisesResponse();
itemMAC1.PremiseName = dtMacs.Tables[0].Rows[index]["PremiseName"].ToString().Trim();
itemMAC1.Alias = dtMacs.Tables[0].Rows[index]["Alias"].ToString().Trim();
premises.Add(itemMAC1);
}
}
catch (Exception ex)
{
Email2.SendError("Premises.GetPremises:" + ex.ToString(), emailAlias);
Shared.PremisesResponse itemMAC1 = new Shared.PremisesResponse();
itemMAC1.PremiseName = "ERROR";
itemMAC1.Alias = ex.ToString();
premises.Add(itemMAC1);
}
return premises;
}
The class Shared.Premise:
public class PremisesResponse
{
public string PremiseName;
public string Alias;
}
In my WP8.1 client app:
public async static Task<List<D2>> GetPremises( string emailaddress)
{
List<D2> premises = new List<D2>();
try
{
using (var client = new HttpClient())
{
var resp = await client.PostAsJsonAsync("http://my url/NativeApp/Default.aspx/GetPremises",
new { emailaddress = emailaddress });
var str = await resp.Content.ReadAsStringAsync();
var premisesResponse = JsonConvert.DeserializeObject<List<D2>>(str);
foreach (var pr in premisesResponse)
{
D2 d2 = new D2();
d2.Alias = pr.Alias;
d2.PremiseName = pr.PremiseName;
premises.Add(d2);
}
}
}
catch (Exception ex)
{
//evMessage(Enums.MessageType.Error, serverRegister);
}
return premises;
}
And the objects I am using in my client:
public class D2
{
public string __type { get; set; }
public string PremiseName;
public string Alias;
}
public class PremisesResponse
{
public D2 d { get; set; }
}
'var str' returns this value:
{"d":[{"__type":"InformedMotionBiz.Shared+PremisesResponse","PremiseName":"Informatica 2000","Alias":"9A5C3-E1945-3D315-BB43C"},{"__type":"InformedMotionBiz.Shared+PremisesResponse","PremiseName":"My Office","Alias":"40387-69918-FC22F-C444B"}]}
The error occurs on this line:
var premisesResponse = JsonConvert.DeserializeObject<List<PremisesResponse>>(str);
The error message is:
[Informed.D2]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To 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 from a JSON object.
Path 'd', line 1, position 5.
I have no problems returning a single value, just with returning a list of this object.
Any pointers would be helpful.
Thanks
You're trying to deserialize a List<D2> rather than a single D2 object:
public class PremisesResponse
{
public D2[] d { get; set; }
}
And then simply:
PremisesResponse response = JsonConvert.DeserializeObject<PremisesResponse>(str);

Parsing JSON page

Been trying to figure out how to parse out "in_reply_to_status_id_str -> id_str" form the twitter search page:
https://twitter.com/phoenix_search.phoenix?q=hello&headers%5BX-Twitter-Polling%5D=true&headers%5BX-PHX%5D=true&since_id=203194965877194752&include_entities=1&include_available_features=1&contributor_details=true&mode=relevance&query_source=unknown
Anyone that could write a small example to show how it can be done?
Using Json.Net
dynamic jObj = JsonConvert.DeserializeObject(new WebClient().DownloadString("your url"));
foreach (var item in jObj.statuses)
{
Console.WriteLine("{0} {1}", item.in_reply_to_status_id_str, item.id_str);
}
SO here is where I pull my Json, this is where my list gets made, which you all ready have:
public JsonResult AllStatuses() //from the json called in the _client view
{
var buildStatuses = new List<BuildStatus>();
var projects = Client.AllProjects();
foreach (var project in projects)
{
try
{
var buildConfigs = Client.BuildConfigsByProjectId(project.Id);
foreach (var buildConfig in buildConfigs)
{
var b = new BuildStatus();
var build = Client.LastBuildByBuildConfigId(buildConfig.Id);
var status = build.Status; // Used to loop through BuildConfigID's to find which is a FAILURE, SUCCESS, ERROR, or UNKNOWN
var change = Client.LastChangeDetailByBuildConfigId(buildConfig.Id); // Provides the changeID
var changeDetail = Client.ChangeDetailsByChangeId(change.Id); // Provides the username, this one populates the usernames
if (changeDetail != null)
b.user = changeDetail.Username;
b.id = buildConfig.Id.ToString();
// If the date isn't null place the start date in long format
if (build.StartDate != null)
b.date = build.StartDate.ToString();
// If block; set the status based on the BuildconfigID from the var status
if (status.Contains("FAILURE")){
b.status = "FAILURE";
}
else if (status.Contains("SUCCESS")){
b.status = "SUCCESS";
}
else if (status.Contains("ERROR")){
b.status = "ERROR";
}
else{
b.status = "UNKNOWN";
}
buildStatuses.Add(b);
}
} catch { }
}
var query = buildStatuses.OrderBy(x => x.status); // Create a sorted list from Error - Unknown
return Json(query, JsonRequestBehavior.AllowGet);
Then I copied the JsonConverter I linked you too.
On my Website I finally pulled apart the list of Json with.
public JsonResult AllStatuses() //from the json called in the _client view
{
List<Client> clients = storeDB.Clients.Include("Projects").Include("Projects.Builds").ToList();
var buildStatuses = new List<BuildStatus>();
foreach (var client in clients) {
// Network credentials
// Used to get the Json Service request // URL here: client.ClientURL
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:81/Status/AllStatuses");
var response = request.GetResponse();
var reader = new StreamReader(response.GetResponseStream());
var responseString = reader.ReadToEnd();
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters((new[] { new DynamicJsonConverter() }));
dynamic obj = serializer.Deserialize(responseString, typeof(object)) as dynamic;
foreach (var objects in obj) // Pull apart the dynamic object
{
var id = objects.id;
var status = objects.status;
var date = objects.date;
var user = objects.user;
var bs = new BuildStatus();
try
{
bs.status = status;
bs.date = date;
bs.id = id;
bs.user = user;
}
catch { throw; }
buildStatuses.Add(bs);
}
}
return Json(buildStatuses, JsonRequestBehavior.AllowGet);
}
Go for a jQuery approach:
var obj = jQuery.parseJSON(jsonString);
alert(obj.in_reply_to_status_id_str.id_str);
You can use this json libraryfor accomplish this.
You could also use the DataContractJsonSerializer class available in .NET once you add a reference to System.Runtime.Serialization.
All you need to do is a create two DataContract classes. Something like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
namespace MyNamespace
{
[DataContract]
public class TwitterObject
{
[DataMember(Name = "statuses")]
public TwitterStatus[] Statuses { get; set; }
}
[DataContract]
public class TwitterStatus
{
[DataMember(Name = "in_reply_to_status_id_str")]
public string InReplyToStatusIdStr { get; set; }
[DataMember(Name = "id_str")]
public string IdStr { get; set; }
}
}
Then from any other method you wish, you just have to use the DataContractJsonSerializer to build your JSON into a .NET object:
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(TwitterObject));
// assume the twitterResponse is the JSON you receive
MemoryStream memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(twitterResponse));
var twitterJson = jsonSerializer.ReadObject(memoryStream) as TwitterObject;
There may be some typos, but this should give you the hint. I'm currently working on an extensive synchronization between a server app and a website and this is the method I currently use for JSON communication between the two. I've found the combination of DataContracts and DataContractJsonSerializer is easier to use than 3rd party libraries.

Categories