UWP Json to C# conversion - c#

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

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.

Deserializing a JSON file with c#

My problem is
i have this JSON file:
and i have to save it in a list but when i try to print the first element of the list I get a System.ArgumentOutOfRangeException, as if my list is empty. this is my code:
JavaScriptSerializer ser = new JavaScriptSerializer();
Causali o = new Causali();
List<CausaliList> lista = new List<CausaliList>();
WebRequest causali = (HttpWebRequest)WebRequest.Create("http://trackrest.cgestmobile.it/causali");
WebResponse risposta = (HttpWebResponse)CreateCausaliRequest(causali).GetResponse();
Stream data = risposta.GetResponseStream();
StreamReader Leggi = new StreamReader(data);
string output = Leggi.ReadToEnd();
lista = ser.Deserialize<List<CausaliList>>(output);
lst2.Items.Add(lista[0]);
and these are my two class for the saves:
class Causali
{
public int id;
public string causaliname;
public string identificationcode;
public string expired;
}
and
class CausaliList
{
public Causali causali;
}
can you help me solve it?
please try this as your root object:
public class CausaliList
{
public List<Causali> causali { get; set; }
}
then deserilize your object like this:
lista = ser.Deserialize<CausaliList>(output);
finally you can access to list like this:
lst2.Items.Add(lista.causali[0]);
Note: i strongly recommend to use json.NET.
To deserialize the code in c#:
Lets assume you have data in var getContent then you may use this:
dynamic getDesearilize = JsonConvert.DeserializeObject(getContent);

Convert Json Singleton into List Phone 81 UAP

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

how to get origin returned object

Get["/"] = _ =>"some data";
Post["/"] = _ =>new {detail="detail.."};
I need convert response to this format
{
state: state code
data: origin data
}
So, I add a after hook
After.AddItemToEndOfPipeline(ResponseFormatHook);
...
private void ResponseFormatHook(NancyContext ctx)
{
var apiResponse = new APIResponse();
apiResponse.State = ctx.Response.StatusCode;
using(var stream = new MemoryStream())
{
ctx.Response.Contents.Invoke(stream);
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
// get the origin data
var content = reader.ReadToEnd();
apiResponse.Data = content;
}
}
var response = new JsonResponse(apiResponse, new DefaultJsonSerializer());
response.StatusCode = HttpStatusCode.OK;
ctx.Response = response;
}
For Get["/"],it's ok. will return {state:200,data:"some data"}.
But for Post["/"],will return {state:200,data:"{detail:\"detail..\"}"}.The data convert to a string not object.The client can not deserialize at once.
So, how can I get the origin data?
apiResponse.Data=OriginData, this will be OK.
EDIT 1
Maybe I can deserialize the Data like
apiResponse.Data=JsonConvert.Deserialize(apiResponse.Data).
But I think this cost too much,isn't it?
Use IResponseProcessor will touch the origin data.
public class APIResponseProcessor : IResponseProcessor
{
private static readonly IEnumerable<Tuple<string, MediaRange>> extensionMappings =
new[] {new Tuple<string, MediaRange>("json", MediaRange.FromString("application/json"))};
public ProcessorMatch CanProcess(MediaRange requestedMediaRange, dynamic model, NancyContext context)
{
var match = new ProcessorMatch();
match.ModelResult = MatchResult.DontCare;
match.RequestedContentTypeResult = MatchResult.ExactMatch;
return match;
}
public Response Process(MediaRange requestedMediaRange, dynamic model, NancyContext context)
{
var apiResponse = new APIResponse();
apiResponse.Data = model;
return new JsonResponse(apiResponse,new DefaultJsonSerializer());
}
public IEnumerable<Tuple<string, MediaRange>> ExtensionMappings { get { return extensionMappings; } }
}
Use processor instead of After hook.

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