JSON Not Deserializing - c#

This is one of my first ventures into WCF/JSON. I created a WCF Web Service. This is one of my methods. It is how I serialize the datable to JSON.
public string GetPrayers()
{
DataTable myDt = new DataTable();
myDt = sprocToDT("LoadPrayers");
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(myDt, Formatting.None);
return JSONString;
}
This returns a nice JSON Dataset:
{"GetPrayersResult":"[{\"prayerid\":2,\"prayer\":\"Please pray for my
dog Rusty. He has cancer
:(\",\"prayerCategory\":\"General\",\"prayerDate\":\"2017-06-10T21:24:16.1\",\"handle\":\"GuruJee\",\"country\":\"USA\"},{\"prayerid\":1,\"prayer\":\"Help
Me I need a appendectomy
STAT\",\"prayerCategory\":\"Sports\",\"prayerDate\":\"2017-04-10T20:30:39.77\",\"handle\":\"GuruJee\",\"country\":\"USA\"}]"}
When I go to deserialize it I get all nulls. Here is the classes I created:
public class PrayUpPrayers
{
public string prayer { get; set; }
public string prayerid { get; set; }
public string prayerCategory { get; set; }
public string prayerCategoryID { get; set; }
public string prayerDate { get; set; }
public string handle { get; set; }
public string country { get; set; }
}
public class ThePrayer
{
public PrayUpPrayers prayers { get; set; }
}
}
This is how I am retrieving the JSON:
void getData()
{
var request = HttpWebRequest.Create(string.Format(#"URLGoesHere"));
request.ContentType = "application/json";
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
Console.Out.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var content = reader.ReadToEnd();
string foo = content.ToString();
var testing = JsonConvert.DeserializeObject<prayupapp.ModelClasses.PrayUpPrayers>(foo,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
Testing is always null? Is the issue that I am serializing it wrong, could it be the class structure, or is it related to how I am deserializing it. One important note: I checked my JSON on one of these JSONClassesFromC# sites and it only returns the GetPrayersResult as the only class item. Ignoring completely my entire structure.

You didn't provide the code for sprocToDT, but it should create ThePrayer object witch should contain list of PrayUpPrayers
public class ThePrayer
{
public List<PrayUpPrayers> prayers { get; set; }
}
And then you should deserialize ThePrayer object, not PrayUpPrayers.
For example
PrayUpPrayers prayUpPrayers1 = new PrayUpPrayers
{
prayer = "Please pray for my dog Rusty. He has cancer",
prayerid = "2",
prayerCategory = "General",
prayerDate = "2017-06-10T21:24:16.1",
handle = "GuruJee",
country = "USA"
};
PrayUpPrayers prayUpPrayers2 = new PrayUpPrayers
{
prayer = "Help Me I need a appendectomy STAT",
prayerid = "1",
prayerCategory = "Sports",
prayerDate = "2017-04-10T20:30:39.77",
handle = "GuruJee",
country = "USA"
};
ThePrayer thePrayer = new ThePrayer
{
prayers = new List<PrayUpPrayers>
{
prayUpPrayers1, prayUpPrayers2
}
};
myDt in your code should be the same as thePrayer instance in my code.
JSONString = JsonConvert.SerializeObject(myDt, Formatting.None);
will provide Json that looks like
"{\"prayers\":[{\"prayer\":\"Please pray for my dog Rusty. He has
cancer\",\"prayerid\":\"2\",\"prayerCategory\":\"General\",\"prayerCategoryID\":null,\"prayerDate\":\"2017-06-10T21:24:16.1\",\"handle\":\"GuruJee\",\"country\":\"USA\"},{\"prayer\":\"Help
Me I need a appendectomy
STAT\",\"prayerid\":\"1\",\"prayerCategory\":\"Sports\",\"prayerCategoryID\":null,\"prayerDate\":\"2017-04-10T20:30:39.77\",\"handle\":\"GuruJee\",\"country\":\"USA\"}]}"
And deserialize will look like
var testing = JsonConvert.DeserializeObject<prayupapp.ModelClasses.ThePrayer>(foo,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});

that's simple. you should deserilze the output twice. try this:
var output= DeserializeObject<string>(foo);
var testing = JsonConvert.DeserializeObject<prayupapp.ModelClasses.PrayUpPrayers>(output,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});

Related

How can we deserialize JSON data to c# object from API response

I need to deserialize my json data. I am using Newtonsoft.Json for json operations. I tried a lot of method to deserialize this data but i failed. Btw, I need to summarize my system for better understanding. I am posting data every minute to an API. And its response to me. So I am trying to deserialize the response.
What need I do to deserialize this json and use it like a normal c# object? I want to deserialize res variable. Thank you for your interest.
Here is the main code
var data = new SendData
{
Readtime = time,
Stationid = new Guid(_stationid),
SoftwareVersion = softwareVersion,
Period = period,
AkisHizi = akisHizi,
AkisHizi_Status = status,
AKM = akm,
AKM_Status = status,
CozunmusOksijen = cozunmusOksijen,
CozunmusOksijen_Status = status,
Debi = debi,
Debi_Status = status,
DesarjDebi = desarjDebi,
DesarjDebi_Status = status,
KOi = koi,
KOi_Status = status,
pH = ph,
pH_Status = status,
Sicaklik = sicaklik,
Sicaklik_Status = status,
Iletkenlik = iletkenlik,
Iletkenlik_Status = status
};
var res = Services.sendData(data);
MessageBox.Show(res.objects.ToString());
Here is the services model PostData method
private ResultStatus<T> PostData<T>(string url, string data) where T : new()
{
try
{
using (var webClient = new WebClient())
{
webClient.Encoding = Encoding.UTF8;
webClient.Headers.Add("AToken", JsonConvert.SerializeObject(new AToken { TicketId = this.TicketId.ToString() }));
var resp = webClient.UploadString(this.Url + url, data);
return JsonConvert.DeserializeObject<ResultStatus<T>>(resp);
}
}
catch (Exception ex)
{
return new ResultStatus<T>
{
message = ex.Message + System.Environment.NewLine + url
};
}
}
Here is the sendData method
public ResultStatus<object> sendData(SendData data)
{
var res = PostData<object>(this.stationType.ToString() + "/SendData", JsonConvert.SerializeObject(data));
return res;
}
Here is the MessageBox result (json data)
{
'Period': 1,
'ReadTime':
'2022-08-22714:01:00',
'AKM': 65.73,
'AKM_Status': 1,
'CozunmusOksijen': 0.2,
'CozunmusOksijen_Status': 1,
'Debi': 1.0,
'Debi_Status': 1,
'KOi': 25.1,
'KOi_Status': 1
}
Your JSON is probably,
{
"Period": 1,
"ReadTime": "2022-08-22T14:01:00",
"AKM": 65.73,
"AKM_Status": 1,
"CozunmusOksijen": 0.2,
"CozunmusOksijen_Status": 1,
"Debi2": 1.0,
"Debi_Status": 1,
"KOi": 25.1,
"KOi_Status": 1
}
From https://app.quicktype.io/, a C# model would be,
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var thing = Thing.FromJson(jsonString);
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class Thing
{
[JsonProperty("Period")]
public long Period { get; set; }
[JsonProperty("ReadTime")]
public DateTimeOffset ReadTime { get; set; }
[JsonProperty("AKM")]
public double Akm { get; set; }
[JsonProperty("AKM_Status")]
public long AkmStatus { get; set; }
[JsonProperty("CozunmusOksijen")]
public double CozunmusOksijen { get; set; }
[JsonProperty("CozunmusOksijen_Status")]
public long CozunmusOksijenStatus { get; set; }
[JsonProperty("Debi2")]
public long Debi2 { get; set; }
[JsonProperty("Debi_Status")]
public long DebiStatus { get; set; }
[JsonProperty("KOi")]
public double KOi { get; set; }
[JsonProperty("KOi_Status")]
public long KOiStatus { get; set; }
}
public partial class Thing
{
public static Thing FromJson(string json) => JsonConvert.DeserializeObject<Thing>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this Thing self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}
As per https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to?pivots=dotnet-6-0#how-to-read-json-as-net-objects-deserialize
Thing? thing = JsonSerializer.Deserialize<Thing>(res);

Assign values from service response to list of objects

I have the following code in which I am getting result from service as below :
var result=CallService();
response.Alllist = new List<Check>
{
new Check
{
Bundle1 = new Bundle
{
Documents = new List<Document>
{
new Document(), new Document()
}
},
},
new CheckList
{
Bundle1 = new Bundle
{
Documents = new List<Document>
{
new Document(), new Document()
}
},
}
And I am struggling in assigning values to this.
And the response class is
public class Response
{
[DataMember(Order = 1)]
public bool Response { get; set; }
[DataMember(Order = 2)]
public List<Check> Alllist { get; set; }
}
public class Document
{
[DataMember(Order = 1)]
public string DocumentType { get; set; }
[DataMember(Order = 2)]
public string DocumentName { get; set; }
}
public class Bundle
{
[DataMember(Order = 1)]
public string BundleName { get; set; }
[DataMember(Order = 2)]
public string DocumentCategory { get; set; }
[DataMember(Order = 3)]
public string NextBundleName { get; set; }
[DataMember(Order = 4)]
public List<Document> Documents { get; set; }
}
public class Check
{
[DataMember(Order = 2)]
public string TransactionID { get; set; }
[DataMember(Order = 4)]
public Bundle Bundle1 { get; set; }
}
And the service returns ,two instances of system.collection.generic.list with multiple instances. and it returns the values of
BundleName,
DocumentCategory ,
NextBundleName ,
DocumentType ,
DocumentName.
How to take result value and assign to this response?
I am trying to assign like this
int count=0;
foreach (var c in result)
{
response.Alllist[count].Bundle1.BundleName = c
}
but since result is dynamic , I am not able to fetch value as c.BundleName
If response.Alllist is a List<Check> as you demonstrated in your first code block, you can populate the values in this manner:
response.Alllist[0].Bundle1.DocumentCategory = "my category";
response.Alllist[0].Bundle1.Documents[0].DocumentName = "my doc name";
and so on.
Other than that, I really don't know what else to tell you. I'm assuming you know about addressing collections by index, etc. You just have to look at the class composition hierarchy in your second code block, i.e. what classes contain instances or collections of other classes.
Based on my understanding of your question, In similar situation, I have tried something like below. Hope this helps. myclass is class define in my project containing field.
Guid testGuid = guid.empty;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync(testData.customerAccountURL).Result;
if (response.IsSuccessStatusCode)
{
string JSONResponse = response.Content.ReadAsStringAsync().Result;
var rObjects = JsonConvert.DeserializeObject<List<myclass>>(JSONResponse);
testGuid = Guid.Parse(rObjects.First().field1.ToString());
// now use this guid to search for a customer
}
string GuidURL = URL + "/"+ testGuid;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(GuidURL);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "GET";
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(result);
string data = values.ElementAt(0).Value;
}
}

Converting list of objects to json array

I have a List of class objects that have email address and status data members. I am trying to convert these to a json, making sure to have the "operations" word on the array.
This is my class:
class MyClass
{
public string email {get; set; }
public string status { get; set; }
}
This is my current code (not building):
List<MyClass> data = new List<MyClass>();
data = MagicallyGetData();
string json = new {
operations = new {
JsonConvert.SerializeObject(data.Select(s => new {
email_address = s.email,
status = s.status
}))
}
};
This is the JSON I am trying to get:
{
"operations": [
{
"email_address": "email1#email.com",
"status": "good2go"
},
{
"email_address": "email2#email.com",
"status": "good2go"
},...
]
}
EDIT1
I should mention that the data I am getting for this comes from a DB. I am de-serializing a JSON from the DB and using the data in several different ways, so I cannot change the member names of my class.
I believe this will give you what you want. You will have to change your class property names if possible.
Given this class
class MyClass
{
public string email_address { get; set; }
public string status { get; set; }
}
You can add the objects to a list
List<MyClass> data = new List<MyClass>()
{
new MyClass(){email_address = "e1#it.io", status = "s1"}
, new MyClass(){ email_address = "e2#it.io", status = "s1"}
};
Using an anonymous-type you can assign data to the property operations
var json = JsonConvert.SerializeObject(new
{
operations = data
});
class MyClass
{
public string email_address { get; set; }
public string status { get; set; }
}
List<MyClass> data = new List<MyClass>() { new MyClass() { email_address = "email1#email.com", status = "good2go" }, new MyClass() { email_address = "email2#email.com", status = "good2go" } };
//Serialize
var json = JsonConvert.SerializeObject(data);
//Deserialize
var jsonToList = JsonConvert.DeserializeObject<List<MyClass>>(json);
You can try with something like this:
using System.Web.Script.Serialization;
var jsonSerialiser = new JavaScriptSerializer();
var json = jsonSerialiser.Serialize(data);
Here is the simple code
JArray.FromObject(objList);

Why is my json deserialization failing?

I have the following two objects (which I do not control and can not change):
[Serializable]
[DataContract]
public class AddressContactType : BaseModel
{
public AddressContactType();
[DataMember]
public string AddressContactTypeName { get; set; }
}
[Serializable]
[DataContract]
public abstract class BaseModel
{
protected BaseModel();
[DataMember]
public int Id { get; set; }
[DataMember]
public string NativePMSID { get; set; }
[DataMember]
public string PMCID { get; set; }
}
I am using RestClient to make a GET call to retrieve this data in JSON. The request succeeds. The returned JSON is:
[{"Id":0,"NativePMSID":"1","PMCID":"1020","AddressContactTypeName":"Home"},{"Id":0,"NativePMSID":"2","PMCID":"1020","AddressContactTypeName":"Apartment"},{"Id":0,"NativePMSID":"3","PMCID":"1020","AddressContactTypeName":"Vacation"},{"Id":0,"NativePMSID":"3","PMCID":"1020","AddressContactTypeName":"Other"}]
From that point I attempt to deserialize the data in three different ways.
My code:
var request = new RestRequest("AddressContactType", Method.GET);
request.AddHeader("Accept", "application/json");
request.AddParameter("PMCID", "1020");
#region JSON Deserialization
// ---- Attempt #1
var response = client.Execute<AddressContactType>(request);
// ---- Attempt #2
var myResults = response.Content;
var ms = new MemoryStream(Encoding.UTF8.GetBytes(myResults));
var ser = new DataContractJsonSerializer(typeof(AddressContactType));
var result = (AddressContactType)ser.ReadObject(ms);
// ---- Attempt #3
var jsonSettings = new JsonSerializerSettings()
{
Formatting = Formatting.Indented,
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
PreserveReferencesHandling = PreserveReferencesHandling.Objects
};
var result2 = new AddressContactType();
result2 = JsonConvert.DeserializeObject<AddressContactType>(new StreamReader(ms).ReadToEnd(), jsonSettings);
#endregion
Under attempt 1, the RestClient attempt returns the error: "Unable to cast object of type 'RestSharp.JsonArray' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'."
Under attempt 2, the object result is shown with the correct properties (Id, NativePMSID, PMCID and AddressContactTypeName) but they are all null and only one instance of each is shown.
Attempt 3 just returns a null value for result2.
Any suggestions?
Thanks.
It appears the solution to my problem is:
List<AddressContactType> myResults2;
using (Stream ms2 = new MemoryStream(Encoding.UTF8.GetBytes(myResults)))
{
myResults2 = JsonConvert.DeserializeObject<List<AddressContactType>>(new StreamReader(ms2).ReadToEnd());
}
I was close with one of the previous steps, but this gave me a complete list.

Deserialize a restful uri

I'm trying to deserialize a rest uri located at http://ws.geonames.org/countryInfo?lang=it&country=DE and keep getting error (There is an error in XML document (1, 1)). Plug http://ws.geonames.org/countryInfo?lang=it&country=DE into the browser and you can see the result.
I have a class
public class Country
{
public string CountryName {get;set;}
public string CountryCode {get;set;}
}
and the method in my console app is as follows:
static void DeserializeTheXML()
{
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "countryName";
xRoot.IsNullable = true;
XmlSerializer ser = new XmlSerializer(typeof(Country), xRoot);
XmlReader xRdr = XmlReader.Create(new StringReader("http://ws.geonames.org/countryInfo?lang=it&country=DE"));
Country tvd = new Country();
tvd = (Country)ser.Deserialize(xRdr);
Console.WriteLine("Country Name = " + tvd.CountryName);
Console.ReadKey();
}
any ideas on how to deserialize this rest service? thanks..
For serialization to work successfully you need to decorate your objects with the proper serialization attributes or use the XmlAttributeOverrides constructor. Also don't forget that XML is case sensitive and your objects must reflect the XML structure you are deserializing:
public class GeoNames
{
[XmlElement("country")]
public Country[] Countries { get; set; }
}
public class Country
{
[XmlElement("countryName")]
public string CountryName { get; set; }
[XmlElement("countryCode")]
public string CountryCode { get; set; }
}
class Program
{
static void Main()
{
var url = "http://ws.geonames.org/countryInfo?lang=it&country=DE";
var serializer = new XmlSerializer(typeof(GeoNames), new XmlRootAttribute("geonames"));
using (var client = new WebClient())
using (var stream = client.OpenRead(url))
{
var geoNames = (GeoNames)serializer.Deserialize(stream);
foreach (var country in geoNames.Countries)
{
Console.WriteLine(
"code: {0}, name: {1}",
country.CountryCode,
country.CountryName
);
}
}
}
}

Categories