Deserialize JSon result with array - json

I have some problem to read from a json. Here is the json what I get:
{
"LoginName": null,
"EmailAddress": null,
"FirstName": null,
"LastName": null,
"ErrorList": [
{
"ErrorNumber": 5001,
"ErrorMessage": "Validation Error: The UserName field is required.",
"Details": null
},
{
"ErrorNumber": 5001,
"ErrorMessage": "Validation Error: The Password field is required.",
"Details": null
},
{
"ErrorNumber": 1,
"ErrorMessage": "The username or password is not correct!",
"Details": null
}
]
}
Here are my classes:
[DataContract]
public class User
{
[DataMember(Name = "LoginName")]
public string loginName { get; set; }
[DataMember(Name = "EmailAddress")]
public string emailAddress { get; set; }
[DataMember(Name = "LastName")]
public string lastName { get; set; }
[DataMember(Name = "FirstName")]
public string firstName { get; set; }
[DataMember(Name = "ErrorList")]
public ErrorList[] errorList { get; set; }
}
[DataContract]
public class ErrorList
{
[DataMember(Name = "ErrorNumber")]
public int errorNumber { get; set; }
[DataMember(Name = "ErrorMessage")]
public string errorMessage { get; set; }
}
I can get for example the LoginName and EmailAddress, but I can't get the element of ErrorList.
Here is the code for deserialize the json result:
var res = await result.Content.ReadAsStringAsync();
var answer = JsonConvert.DeserializeObject<User>(res);
Email.Text = answer.emailAddress;
It works, but I don't reach the array.
Anyone has any idea to solve this problem?

As #Abdurrahman Köken stated, maybe you should use JSON.NET attributes instead of System.Runtime.Serialization.
Still, this code has nothing wrong with it. Error is somewhere else. Using your User class as-is, with provided JSON, and deserializing it as var answer = JsonConvert.DeserializeObject<User>(yourJsonHere); gives the following:
So, after deserialization
answer.errorList.ToList().ForEach(error =>
Console.WriteLine(#"{0}={1}", error.errorNumber, error.errorMessage));
Outputs
5001=Validation Error: The UserName field is required.
5001=Validation Error: The Password field is required.
1=The username or password is not correct!

You should change DataMember attributes with JsonProperty. This should work:
public class User
{
[JsonProperty("LoginName")]
public string loginName { get; set; }
[JsonProperty("EmailAddress")]
public string emailAddress { get; set; }
[JsonProperty("LastName")]
public string lastName { get; set; }
[JsonProperty("FirstName")]
public string firstName { get; set; }
[JsonProperty("ErrorList")]
public ErrorList[] errorList { get; set; }
}
public class ErrorList
{
[JsonProperty("ErrorNumber")]
public int errorNumber { get; set; }
[JsonProperty("ErrorMessage")]
public string errorMessage { get; set; }
}

Related

Xamarin Forms Json Desrialization

I want to deserialize a JSON coming from a web service, but for some reason I am getting an exception. I searched every question related to this topic but I did not find anything related to this exception. What might me the problem? here is the exception:
Newtonsoft.Json.JsonSerializationException: 'Unexpected token while deserializing object: EndObject. Path '', line 1, position 243.'
Here is my deserialize method:
public async Task<LoginApiResponse> AuthenticateUserAsync(string username, string password)
{
// try
// {
LoginApiRequest loginRequest = new LoginApiRequest()
{
Username = username,
Password = password
};
// serialize object to json
var content = new StringContent(JsonConvert.SerializeObject(loginRequest), Encoding.UTF8, "application/json");
var response = await Client.PostAsync(Constants.LOGIN_URI, content);
response.EnsureSuccessStatusCode();
// get the data on success and serialize it from json
using (var stream = await response.Content.ReadAsStreamAsync())
using (var reader = new StreamReader(stream))
using (var json = new JsonTextReader(reader))
{
System.Diagnostics.Debug.Write(">>>>>>>>>>>>>>>>>>>> " + Serializer.Deserialize<LoginApiResponse>(json));
return Serializer.Deserialize<LoginApiResponse>(json);
}
// }
/* catch (Exception ex)
{
return null;
}*/
}
here is the Request model:
public class LoginApiRequest
{
[JsonProperty("Username")]
public string Username { get; set; }
[JsonProperty("Password")]
public string Password { get; set; }
public LoginApiRequest() { }
}
here is the Response Model:
public class LoginApiResponse : MessageStatus
{
[JsonProperty("Data")]
public User Data { get; set; }
public LoginApiResponse() { }
}
here is the User model:
public class User
{
[JsonProperty("Address")]
public string Address { get; set; }
[JsonProperty("BloodType")]
public string BloodType { get; set; }
[JsonProperty("ConfirmPassword")]
public string ConfirmPassword { get; set; }
[JsonProperty("CustomerID")]
public string CustomerID { get; set; }
[JsonProperty("DOB")]
public string DOB { get; set; }
[JsonProperty("Email")]
public string Email { get; set; }
[JsonProperty("ID")]
public int? ID { get; set; }
[JsonProperty("IsActive")]
public bool IsActive { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("Password")]
public string Password { get; set; }
[JsonProperty("Phone")]
public string Phone { get; set; }
[JsonProperty("UserRoleID")]
public int? UserRoleID { get; set; }
[JsonProperty("Username")]
public string Username { get; set; }
public User() { }
}
and here is the the messagestatus:
public class MessageStatus
{
[JsonProperty("Message")]
public string Message { get; set; }
[JsonProperty("Status")]
public int Status { get; set; }
public MessageStatus() { }
}
and finally here is the json:
{
"Message": null,
"Status": 1,
"Data": {
"Address": "Beirut",
"BloodType": null,
"ConfirmPassword": null,
"CustomerID": null,
"DOB": null,
"Email": null,
"ID": 22,
"IsActive": true,
"Name": "tg",
"Password": "123456",
"Phone": "03708424",
"UserRoleID": 1,
"Username": "tg"
}
}
instead of
using (var stream = await response.Content.ReadAsStreamAsync())
using (var reader = new StreamReader(stream))
using (var json = new JsonTextReader(reader))
{
System.Diagnostics.Debug.Write(">>>>>>>>>>>>>>>>>>>> " + Serializer.Deserialize<LoginApiResponse>(json));
return Serializer.Deserialize<LoginApiResponse>(json);
}
try
var json = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<LoginApiResponse>(json)
return data;

Error deserializing DateTime JSON fields in .Net Core 3.0

I've got a WPF / .Net Core 3.0 app which is consuming a Web API.
It executes a GET on an API endpoint and then tries to deserialize the JSON.
However, it's giving an error when trying to deserialize the DateTime fields.
Here's the code:
private HttpClient httpClient = new HttpClient();
private async Task GetClients()
{
var serializer = new DataContractJsonSerializer(typeof(List<ClientGetDto>));
var streamTask = httpClient.GetStreamAsync("https://mywebapp.com/api/Clients");
List<ClientGetDto> clientDtos = serializer.ReadObject(await streamTask) as List<ClientGetDto>;
}
The ClientGetDto model looks like this:
{
public int Id { get; set; }
public string ClientCode { get; set; }
public string ApiUrl { get; set; }
public string CompanyName { get; set; }
public string FranchiseName { get; set; }
public int? ProLicenses { get; set; }
public int? LiteLicenses { get; set; }
public int? ProSalesLicenses { get; set; }
public int? LiteSalesLicenses { get; set; }
public bool? IsActive { get; set; }
public DateTime? StartOfAgreementDate { get; set; }
public int? DebitOrderDay { get; set; }
public DateTime? DebitOrderStartDate { get; set; }
public decimal? ContractAmount { get; set; }
public bool? DebitOrderFormReceived { get; set; }
public bool? CancellationReceived { get; set; }
public DateTime? CancellationDate { get; set; }
public string CompanyRegNo { get; set; }
public string DbUrl { get; set; }
public string DbName { get; set; }
public double? CloudStorageQuota { get; set; }
public string Comments { get; set; }
public int? FranchiseId { get; set; }
public bool? IsTestDb { get; set; }
public bool? IsGumtreeRegistered { get; set; }
public int? FusionClientId { get; set; }
public string CountryCode { get; set; }
}
and the JSON that is returned by the API is:
[
{
"id": 3,
"clientCode": "cx0007",
"apiUrl": "https://mywebapp/api",
"companyName": "ACME Company",
"franchiseName": "ACME Franchise",
"proLicenses": 1,
"liteLicenses": 0,
"proSalesLicenses": 0,
"liteSalesLicenses": 0,
"isActive": true,
"startOfAgreementDate": "2007-08-01T00:00:00",
"debitOrderDay": 1,
"debitOrderStartDate": "2012-03-01T00:00:00",
"contractAmount": 695.00,
"debitOrderFormReceived": true,
"cancellationReceived": false,
"cancellationDate": "2012-10-18T00:00:00",
"companyRegNo": "",
"dbUrl": "mydb.co.za",
"dbName": "db1",
"cloudStorageQuota": 5.0,
"comments": null,
"franchiseId": null,
"isTestDb": false,
"isGumtreeRegistered": false,
"fusionClientId": null,
"countryCode": "US"
},
...
]
The error I'm getting is:
"There was an error deserializing the object of type
System.Collections.Generic.List`1[[PropWorxManager.DTOs.ClientGetDto,
PropWorxManager, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null]].
DateTime content '2007-08-01T00:00:00' does not
start with '\/Date(' and end with ')\/' as required for
JSON."} System.Runtime.Serialization.SerializationException
After some research I tried this:
var settings = new DataContractJsonSerializerSettings
{
DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat("o")
};
var serializer = new DataContractJsonSerializer(typeof(List<ClientGetDto>), settings);
But that then gives this error:
"There was an error deserializing the object of type
System.Collections.Generic.List`1[[PropWorxManager.DTOs.ClientGetDto,
PropWorxManager, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null]].
String '2007-08-01T00:00:00' was not recognized
as a valid
DateTime."} System.Runtime.Serialization.SerializationException
Any suggestions would be welcome. Thank you.
P.S. The API is also written in .Net Core 3.0 if that helps...
This worked:
var settings = new DataContractJsonSerializerSettings
{
DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat("o")
};
var serializer = new DataContractJsonSerializer(typeof(List<ClientGetDto>), settings);

Get item from JSON Odata list for UWP

I have been having a hard time trying to figure this out that I've just about torn out all my hair now.
Using this section of code (Added a var result that I looking at with a stoppoint):
public async Task<string> GetHttpSPContentWithToken(string url, string token)
{
var httpClient = new System.Net.Http.HttpClient();
System.Net.Http.HttpResponseMessage response;
try
{
var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
//Add the token in Authorization header
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
response = await httpClient.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<SharePointListItems.Fields>(content);
return content;
}
catch (Exception ex)
{
return ex.ToString();
}
}
The content that I receive is this (updated getting rid of extra information):
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('root')/lists('FBA0AB63-8453-4BB9-AA17-142A5D72A50D')/items/$entity",
"#odata.etag": "\"60d40002-0f08-4f29-afa7-0287137b863b,1\"",
"createdDateTime": "2018-08-07T14:28:47Z",
"eTag": "\"60d40002-0f08-4f29-afa7-0287137b863b,1\"",
"id": "1",
"lastModifiedDateTime": "2018-08-07T14:28:47Z",
"webUrl": "https://XXXX.sharepoint.com/Lists/TestList/1_.000",
"createdBy": {
"user": {
"email": "XXXX#XXXX.onmicrosoft.com",
"id": "b5f81cc6-f8b7-46b7-8e10-6ce1b9689c23",
"displayName": "TK"
}
},
"lastModifiedBy": {
"user": {
"email": "XXXX#XXXX.onmicrosoft.com",
"id": "b5f81cc6-f8b7-46b7-8e10-6ce1b9689c23",
"displayName": "TK"
}
},
"parentReference": {},
"contentType": {
"id": "0x010001403BD420356E4ABE3B63E5AEC0713D"
},
"fields#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('root')/lists('FBA0AB63-8453-4BB9-AA17-142A5D72A50D')/items('1')/fields/$entity",
"fields": {
"#odata.etag": "\"60d40002-0f08-4f29-afa7-0287137b863b,1\"",
"Title": "1",
"UserName": "TK",
"UserAge": "47",
"UserTitle": "Developer"
}
}
I just want the values forUserAge, UserName, and UserTitle to put each into a textbox, but not sure how to pull them out.
I am pretty sure that I need to set up a class of some sort, but it is the #odata parts that are breaking my back.
Everything that I have tried just gives me back a null value. I see the value there, just not sure how to parse/pull it out.
I have looked at this (updated):
using Newtonsoft.Json;
using System;
public class SharePointListItems
{
public class UserCreated
{
public string email { get; set; }
public string id { get; set; }
public string displayName { get; set; }
}
public class CreatedBy
{
public UserCreated user { get; set; }
}
public class UserModified
{
public string email { get; set; }
public string id { get; set; }
public string displayName { get; set; }
}
public class LastModifiedBy
{
public UserModified user { get; set; }
}
public class ParentReference
{
}
public class ContentType
{
public string id { get; set; }
}
public class Fields
{
[JsonProperty("#odata.etag")]
public string ODataETag { get; set; }
public string Title { get; set; }
public string UserName { get; set; }
public string UserAge { get; set; }
public string UserTitle { get; set; }
}
public class RootObject
{
[JsonProperty("#odata.context")]
public string ODataContext { get; set; }
[JsonProperty("#odata.etag")]
public string ODataETag { get; set; }
public DateTime createdDateTime { get; set; }
public string eTag { get; set; }
public string id { get; set; }
public DateTime lastModifiedDateTime { get; set; }
public string webUrl { get; set; }
public CreatedBy createdBy { get; set; }
public LastModifiedBy lastModifiedBy { get; set; }
public ParentReference parentReference { get; set; }
public ContentType contentType { get; set; }
[JsonProperty("fields#odata.context")]
public string FieldsODataContext { get; set; }
public Fields fields { get; set; }
}
}
But then I run into the issue that there is two [JsonProperty("#odata.etag")].
The [JsonProperty] custom attribute is added to the C# property that actually holds that value. Instead of putting the attribute on the Title or createDateTime property, you need to put them on their own properties:
public class RootObject
{
[JsonProperty("#odata.context")]
public string ODataContext { get; set; }
[JsonProperty("#odata.etag")]
public string ODataETag { get; set; }
// No attribute needed here
public DateTime createdDateTime { get; set; }
// etc...
Also, you are trying to parse the content as a Fields class, but it is a RootObject; you need to use
JsonConvert.DeserializeObject<SharePointListItems.RootObject>(content)
To get the object.

Parse Json to List

I want to parse a json to List how can we do that. I have tried the following code but it didnt worked
Dictionary<string, object> pGateways=(Dictionary<string,object>)Json.JsonParser.FromJson(jsonString);
List<object> creditOptions = new List<object>();
creditOptions = (List<object>)pGateways;
And after getting it int list i want to loop through it
Here is my sample json
{
"MessageCode": "CS2009",
"Status": "Y",
"ErrorCode": "0",
"ErrorDescription": "Success",
"account":
{
"card":
[
{
"cardend": "asd",
"token": "aads",
"cardstart": "asdad",
"accounttype": "asda",
"cardnetwork": "as",
"issuer": "asd",
"customername": "a",
"expdate": "04/2018"
},
{
"cardend": "asda",
"token":"adssadsa",
"cardstart": "asd",
"accounttype": "asd",
"cardnetwork": "asd",
"issuer": "asda",
"customername": "asd",
"expdate": "03/2016"
}
],
"bank": []
}
}
The best option could be to use the JsonConvert in order to parse Json into a List.
Reference: JSON Parsing in Windows Phone
You can use Json.Net.
To install Json.NET use NugetGallery : Json.net Nugets Gallery
And you can use json2Csharp.com for generate c# classes from json
The JSON string you posted is not suitable for straight-forward deserialization to List. The easiest thing to do is use the online JSON 2 CSharp tool to generate classes and deserialize the json string to it. Here is an example of the generated classes:
public class Card
{
public string cardend { get; set; }
public string token { get; set; }
public string cardstart { get; set; }
public string accounttype { get; set; }
public string cardnetwork { get; set; }
public string issuer { get; set; }
public string customername { get; set; }
public string expdate { get; set; }
}
public class Account
{
public List<Card> card { get; set; }
public List<object> bank { get; set; }
}
public class RootObject
{
public string MessageCode { get; set; }
public string Status { get; set; }
public string ErrorCode { get; set; }
public string ErrorDescription { get; set; }
public Account account { get; set; }
}
And here is the logic for deserialization:
var root = JsonConvert.DeserializeObject<RootObject>(jsonStr);
where the jsonStr variable holds the json string you posted.
You need to use json2csharp tool to generate classes and deserialize the JSON string to list.
Here is the Classes generated from your JSON string.
public class Card
{
public string cardend { get; set; }
public string token { get; set; }
public string cardstart { get; set; }
public string accounttype { get; set; }
public string cardnetwork { get; set; }
public string issuer { get; set; }
public string customername { get; set; }
public string expdate { get; set; }
}
public class Account
{
public List<Card> card { get; set; }
public List<object> bank { get; set; }
}
public class RootObject
{
public string MessageCode { get; set; }
public string Status { get; set; }
public string ErrorCode { get; set; }
public string ErrorDescription { get; set; }
public Account account { get; set; }
}
and Deserialize your JSON object using JsonConvert,
Suppose e.result is your JSON string then
var rootObject = JsonConvert.DeserializeObject<RootObject>(e.Result);
foreach (var blog in rootObject.Card)
{
//access your data like this- `blog.cardend;` or `blog.token;`
}

Cannot Deserialise Json array into type string

Following id my piece of code which deserialise Json string.
response = "{\"success\":\"yes\",\"error\":\"\",\"message\":\"\",\"arguments\":[{\"id\":\"72820\",\"rowNo\":\"1\",\"userId\":\"40\",\"entityId\":\"3486\",\"value\":\"search Panel\",\"typeCategory\":\"3\"}]}";
erpAPIResponse basicResponse = JsonConvert.DeserializeObject<erpAPIResponse>(response);
Result is JSON string which is deserialised into erpAPIResponse.
My erpAPIResponse is as follows:
public string success { get; set; } // getting and setting the success
public string error { get; set; } // getting and setting the error
public string message { get; set; } // getting and setting the message
public string arguments { get; set; } // getting and setting the arguments
// public string result { get; set; }
I have verify json through JSON Lint and it is saying it is valid JSON string. So why i am getting this errorr?
As your json structure is like below:
{
"success": "yes",
"error": "",
"message": "",
"arguments": [
{
"id": "72820",
"rowNo": "1",
"userId": "40",
"entityId": "3486",
"value": "search Panel",
"typeCategory": "3"
}
]
}
Here you cannot deserialize the arguments array in a string. So you need to redefine the erpAPIResponse class like below using json2csharp utility:
public class erpAPIResponse
{
public string success { get; set; }
public string error { get; set; }
public string message { get; set; }
public List<Argument> arguments { get; set; }
}
public class Argument
{
public string id { get; set; }
public string rowNo { get; set; }
public string userId { get; set; }
public string entityId { get; set; }
public string value { get; set; }
public string typeCategory { get; set; }
}
Now you should have no problem deserializing with your original statements:
response = "{\"success\":\"yes\",\"error\":\"\",\"message\":\"\",\"arguments\":[{\"id\":\"72820\",\"rowNo\":\"1\",\"userId\":\"40\",\"entityId\":\"3486\",\"value\":\"search Panel\",\"typeCategory\":\"3\"}]}";
erpAPIResponse basicResponse = JsonConvert.DeserializeObject<erpAPIResponse>(response);