I'm using the Json.Net Framework and I'm trying to convert multiple Json strings to different objects using only one method to achieve it.
To create the objects to store the Json data I'm using this website.
So far, I've managed to have one method to convert for one object (in this case RootObject) with the code bellow:
public class WebService
{
protected string jsonstring;
// Other code
// Method
public RootObject stringToObject(){
return JsonConvert.DeserializeObject<RootObject>(this.jsonstring);
}
}
// Object
public class RootObject
{
public string id { get; set; }
public string name { get; set; }
public string title { get; set; }
}
// Usage
WebService ws = new WebService ("http://example.com/json_string.json");
RootObject data = ws.stringToObject ();
The thing is that I have two more objects that I need to convert a Json string into:
public class RootObject2
{
public string id { get; set; }
public string menu_id { get; set; }
public string language { get; set; }
public string title { get; set; }
}
public class RootObject3
{
public string id { get; set; }
public string menu_id { get; set; }
public string position { get; set; }
public string active { get; set; }
}
I've tried to change the method return type to a generic type but it didn't work:
public object stringToObject(){
return JsonConvert.DeserializeObject<object>(this.jsonstring);
}
How can I have the method return type dynamic so I can do something like this:
WebService ws = new WebService ("http://example.com/json_string.json");
RootObject data = ws.stringToObject ();
WebService ws2 = new WebService ("http://example.com/json_string2.json");
RootObject2 data2 = ws2.stringToObject ();
WebService ws3 = new WebService ("http://example.com/json_string3.json");
RootObject3 data3 = ws3.stringToObject ();
Why not make your WebService be generic?
public class WebService<T>
{
protected string jsonstring;
// Other code
// Method
public T stringToObject(){
return JsonConvert.DeserializeObject<T>(this.jsonstring);
}
}
Then do
var ws = new WebService<RootObject>("http://example.com/json_string.json");
var data = ws.stringToObject ();
Or if you prefer, you can just make stringToObject be generic:
public class WebService
{
protected string jsonstring;
// Other code
// Method
public T stringToObject<T>(){
return JsonConvert.DeserializeObject<T>(this.jsonstring);
}
}
And do:
var data = ws.stringToObject<RootObject>();
Related
I'm trying to fetch Symptoms from an API. I can fetch them already and I'm serializing it inside a class succesfully. The result looks like in image that i share at below:
There are just IDs and Names inside them. The second table from API is like that:
So here my Entity Class;
using System.Collections.Generic;
public class SymptomousInBodySublocations
{
public int ID { get; set; }
public string Name { get; set; }
public bool HasRedFlag { get; set; }
public ICollection<BodyLocations> HealthSymptomLocationIDs { get; set; }
public string ProfName { get; set; }
public List<string> Synonyms { get; set; }
}
And my Serialize Method:
public static List<SymptomousInBodySublocations> SymptomsInBodySublocations()
{
var client = new RestClient("https://priaid-symptom-checker-v1.p.rapidapi.com/symptoms/31/man?format=json&language=en-gb");
var request = new RestRequest(Method.GET);
request.AddHeader("x-rapidapi-host", "priaid-symptom-checker-v1.p.rapidapi.com");
request.AddHeader("x-rapidapi-key", "<api-key>");
List<SymptomousInBodySublocations> SymptomsInBodySublocationsList = new List<SymptomousInBodySublocations>();
var response = client.Execute<List<SymptomousInBodySublocations>>(request);
foreach(SymptomousInBodySublocations variables in response.Data)
{
SymptomsInBodySublocationsList.Add(variables);
}
return SymptomsInBodySublocationsList;
}
And my BodyLocations Class:
public class BodyLocations
{
public int ID { get; set; }
public string Name { get; set; }
}
In this point when i tried to fetch my data inside my List<BodyLocations>() the response.Data is empty. What should i do?
HealthSymptomLocationIDs isn't an object, looking at the response it is an array of integers.
Changing the field to match the response should populate the field with the integer values from the API
public List<int> HealthSymptomLocationIDs { get; set; }
I have a string stream returning JSON data from and API that looks like this:
"{\"Recs\":
[
{\"EID\":\"F67_24_6\",\"ReturnPeriod\":\"1\",\"GageStation\":\"NA\"},
{\"EID\":\"T67_24_6\",\"ReturnPeriod\":\"2.37\",\"GageStation\":\"Magueyes Island\"},
{\"EID\":\"R67_24_6\",\"ReturnPeriod\":\"1\",\"GageStation\":\"50147800\"}
]}"
I am trying to deserialize it to return this:
{"Recs":[
{"EID":"F67_24_6","ReturnPeriod":"1","GageStation":"NA"},
{"EID":"T67_24_6","ReturnPeriod":"2.37","GageStation":"Magueyes Island"},
{"EID":"R67_24_6","ReturnPeriod":"1","GageStation":"50147800"}
]}
I am using these public classes to structure the return:
public class New_Events_Dataset
{
public string EID { get; set; }
public string ReturnPeriod { get; set; }
public string GageStation { get; set; }
}
public class NewRootObject
{
public List<New_Events_Dataset> Reqs { get; set; }
}
When I try to apply this later, I basically get a return of {"Reqs":null}. What am I doing wrong here?
var jsonResponse = JsonConvert.DeserializeObject<NewRootObject>(strresult);
string json = new JavaScriptSerializer().Serialize(jsonResponse);
return json;
I think Reqs should be Recs:
public class NewRootObject
{
public List<New_Events_Dataset> Reqs { get; set; }
}
try:
public class NewRootObject
{
public List<New_Events_Dataset> Recs { get; set; }
}
Rename Reqs to Recs and create default constructor of class and instantiate Recs list
public class NewRootObject
{
List<New_Events_Dataset> Recs { get; set; }
public NewRootObject()
{
Recs = new List<New_Events_Dataset>();
}
}
I'm using Newwtonsoft.JSON for build my json file, actually what I did is create different classes models, as this:
class GeneralModel
{
public string Language { get; set; }
}
and then for build the json file:
GeneralModel lsModel = new GeneralModel();
string json = JsonConvert.SerializeObject(lsModel);
File.WriteAllText(settingsFilePath, json);
this will create a json that contains Language, but I need to put in this json different classes, what I need is set an index that contains each class name, for example:
"GeneralModel": {
"Language" : "english"
},
"AnoherClassName": {
"ClassProperty" : value
}
how can I do this with Newtonsoft?
public class GeneralModel
{
public string Language { get; set; }
}
public class AnotherModel
{
public string AnotherProperty { get; set; }
}
public class SuperClass
{
public GeneralModel generalModel { get; set; }
public AnotherModel anotherModel { get; set; }
}
then
SuperClass s = new WMITest.SuperClass();
s.generalModel = new GeneralModel();
s.generalModel.Language = "language";
s.anotherModel = new AnotherModel();
s.anotherModel.AnotherProperty = "example";
string json = JsonConvert.SerializeObject(s);
i have json string as
{"AccountNo":"345234533466","AuthValue":"{\"TopUpMobileNumber\":\"345234533466\",\"VoucherAmount\":\"100\"}"}
to parse this string i have created class as
public class UserContext
{
public string AccountNo { get; set; }
public string AuthValue { get; set; }
}
in AuthValue it gives me output as {\"TopUpMobileNumber\":\"345234533466\",\"VoucherAmount\":\"100\"} which is absolutely correct. now i want to modify my class in such way that i want AuthValue in string format as well and in seprate member variable format.
so i modify my class in this way but it gives error
public class UserContext
{
public string AccountNo { get; set; }
public string AuthValue { get; set; }
public Auth ????? { get; set; }
}
public class Auth
{
public string TopUpMobileNumber { get; set; }
public string VoucherAmount { get; set; }
}
My requirement is
AuthValue whole json string i required
in another variable i want member wise values
Parsing Logic
UserContext conObj1 = new UserContext();
conObj1 = JsonConvert.DeserializeObject<UserContext>(context);
Note : No modification in json string is allowed.
I'm not very familiar with JsonConvert or Json.NET so I'm not sure what options are available for that. Personally I'd just call the deserializer again immediately afterwards.
UserContext conObj1 = new UserContext();
conObj1 = JsonConvert.DeserializeObject<UserContext>(context);
conObj1.AuthObject = JsonConvert.DeserializeObject<Auth>(conObj1.AuthValue);
You could move this into the class if you wanted and call it directly off the deserialized class.
public class UserContext
{
public string AccountNo { get; set; }
public string AuthValue { get; set; }
public Auth AuthObject { get; private set; }
internal UserContext Deserialize()
{
// Serialize the object
this.AuthObject = JsonConvert.DeserializeObject<Auth>(this.AuthValue);
// Return this object for a simple single-line call.
return this;
}
}
// Single object
UserContext conObj1 = new UserContext();
conObj1 = JsonConvert.DeserializeObject<UserContext>(context).Deserialize();
// Enumeration of object (given that this is supported in JsonConvert)
IEnumerable<UserContext> conObjs = JsonConvert.DeserializeObject<IEnumerable<UserContext>(contexts).Select(c => c.Deserialize()).ToList();
Or if you feel self hating you could go as far as doing the deserialization at the time the property is accessed (although I would avoid this at almost all costs due to the numerous issues it can cause).
public class UserContext
{
private Auth m_auth;
public string AccountNo { get; set; }
public string AuthValue { get; set; }
public Auth AuthObject
{
get
{
if (this.m_auth == null)
{
this.m_auth = JsonConvert.DeserializeObject<Auth>(this.AuthValue);
}
return this.m_auth;
}
}
}
I would suggest using two classes - one for the JSON you're actually receiving, and then one for the object model you want to use:
public class JsonUserContext
{
public string AccountNo { get; set; }
public string AuthValue { get; set; }
}
public class UserContext
{
public string AccountNo { get; set; }
public Auth AuthValue { get; set; }
}
public class Auth
{
public string TopUpMobileNumber { get; set; }
public string VoucherAmount { get; set; }
}
...
var jsonUserContext = JsonConvert.DeserializeObject<JsonUserContext>(json);
var authJson = jsonUserContext.AuthValue;
var userContext = new UserContext {
AccountNo = jsonUserContext.AccountNo,
AuthValue = JsonConvert.DeserializeObject<JsonUserContext>(authJson);
};
i would like use uknown object from JS like this
{"aa":{"abcd
1":{"uio":[],"uio2":[],"uio3":["opee1","opee2","opee3"]},"abcd
2":null,"abcd 3":null,"abcd 4":null}}
sent into MVC with contentType 'application/json'. This object has no permament keys, like this name "abcd 1" can be another name in future.
i have function Test(Object aa) and question is, what type i must use for unknown array of objects or strings. Thanks
Have you tried this website before: http://json2csharp.com/ ?
Though the ASP.NET 4.0 built in JSON to C# parsing/serialization works great and in most cases you can just define a simple C# class that models the "signature" of your JSON and get the correct C# representation of your JSON with a call to something like Test(MyCSharpJsonObj aa), you seem to need something more robust. Note with the code you are about to see below, don't think you can overload your functions like so Test(ListData1 aa), Test(ListData2 aa), ASP.NET won't correctly call the right function for you on request from client and may not even compile correctly, if using Web API, not sure.
You more likely will have to call the right function from the client who is intimate with the JSON being sent in the request like so: Test1(ListData1 aa), Test2(ListData2 aa) using the code like below to assist you:
[Serializable]
[DataContract]
public class ListData1
{
[DataMember]
public string r0 { get; set; }
[DataMember]
public string r1 { get; set; }
[DataMember]
public string r2 { get; set; }
[DataMember]
public List<Data1> optdata { get; set; }
public ListData1() { }
public string ToJson()
{
return JSONHelper.Serialize<ListData1>(this);
}
}
[Serializable]
[DataContract]
public class Data1
{
[DataMember]
public string label { get; set; }
[DataMember]
public string d0 { get; set; }
[DataMember]
public string d1 { get; set; }
public Data1() { }
public string ToJSON()
{
return JSONHelper.Serialize<Data1>(this);
}
}
[Serializable]
[DataContract]
public class ListData2
{
[DataMember]
public string r0 { get; set; }
[DataMember]
public string r1 { get; set; }
[DataMember]
public string r2 { get; set; }
[DataMember]
public List<Data2> optdata { get; set; }
public ListData2() { }
public string ToJson()
{
return JSONHelper.Serialize<ListData2>(this);
}
}
[Serializable]
[DataContract]
public class Data2
{
[DataMember]
public string label { get; set; }
[DataMember]
public string d0 { get; set; }
[DataMember]
public string d1 { get; set; }
[DataMember]
public string d2 { get; set; }
public Data2() { }
public string ToJSON()
{
return JSONHelper.Serialize<Data2>(this);
}
}
public static class JSONHelper
{
public static string Serialize<T>(T obj)
{
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, obj);
string retVal = Encoding.UTF8.GetString(ms.ToArray());
return retVal;
}
public static T Deserialize<T>(string json)
{
if (string.IsNullOrEmpty(json))
{
return default(T);
}
T obj = Activator.CreateInstance<T>();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms);
ms.Close();
return obj;
}
}
For my personal experience, the most useful way to consume Json inside a code is to use dynamics. Basically, instead of serializing/deserializing to specific type, you convert json object to dynamic one.
In this case you loose compile time validation, but get ability to support of any document structure.
In MVC4 you may use build-in Json.Decode() method from System.Web.Helpers.dll which will return you dynamic object. Otherwise, there are lots of libraries for that specific purpose, like Json.Net
Finally I found solution. Use Newtonsoft.Json and this code as sample for dynamic data structure:
$.ajax({
...
data: {data: JSON.stringify({first: "name", next: ["a", "b"], last: {o: "in"}})}
})
[HttpPost]
public JsonResult SaveMenu(String data)
{
dynamic JData = JObject.Parse(data);
//--now JData.first == "name"
if (JData.last is JObject)
{
}
//--or dynamic foreach
foreach (dynamic own in JData)
{
//--own.Name == first, next and last
//--access to variable == JData[own.Name]
if (JData[own.Name] is JArray)
{
foreach (String var in JData[own.Name])
{
}
}
}
}