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])
{
}
}
}
}
Related
All - I've stumbled into a scenario that's causing me quite a bit of grief. I have a json structure (produced by gateio api) which on the face of it, looks super simple to deserialize into an object. the jsonTickerString looks like the below:
{
"method":"ticker.update",
"params":[
"BTC_USDT",
{
"period":86400,
"open":"46721.06",
"close":"48130.43",
"high":"48758.59",
"low":"46330.3",
"last":"48130.43",
"change":"2.95",
"quoteVolume":"2246.8399550054",
"baseVolume":"106183751.468785134437"
}
],
"id":null
}
However, this is proving to be deceptively funky when trying to push it into an object model. I derived the object model below and thought we were all set to go:
public partial class GateIoTicker
{
[JsonProperty("method")]
public string Method { get; set; }
[JsonProperty("params")]
public List<ParamElement> Params { get; set; }
[JsonProperty("id")]
public object Id { get; set; }
}
public class ParamClass
{
[JsonProperty("period")]
public long Period { get; set; }
[JsonProperty("open")]
public string Open { get; set; }
[JsonProperty("close")]
public string Close { get; set; }
[JsonProperty("high")]
public string High { get; set; }
[JsonProperty("low")]
public string Low { get; set; }
[JsonProperty("last")]
public string Last { get; set; }
[JsonProperty("change")]
public string Change { get; set; }
[JsonProperty("quoteVolume")]
public string QuoteVolume { get; set; }
[JsonProperty("baseVolume")]
public string BaseVolume { get; set; }
}
public partial struct ParamElement
{
public string coinName;
public ParamClass quoteParams;
public static implicit operator ParamElement(ParamClass quoteparams)
{
return new ParamElement { quoteParams = quoteparams };
}
public static implicit operator ParamElement(string coinname)
{
return new ParamElement { coinName = coinname };
}
}
I then set about populating the object using the standard Json.Net approach:
var gateIoTicker = JsonConvert.DeserializeObject<GateIoTicker>(jsonTickerString);
However, although this correctly deserializes the string element in the "params" object, no amount of coersion will bring about a deserialization of the ParamClass object.
Am I missing something very obvious here?? I've spent an inordinate amount of time trying to figure this out and think it's now time to solicit some superior brain power.
Hope this scans as expected...
[Edit] - further to Serge's suggestion, i took his code and added it as a method on my GatIoTicker object. Would have preferred an option that desrializes using attributes, but this works perfectly. Refactored code looks like:
public partial class GateIoTicker
{
[JsonProperty("method")]
public string Method { get; set; }
[JsonProperty("params")]
public List<ParamElement> Params { get; set; }
[JsonProperty("id")]
public object Id { get; set; }
public GateIoTicker FromJson(string json)
{
var jsonObject = JObject.Parse(json);
var pars = jsonObject["params"] as JArray;
var paramElement = new ParamElement();
foreach (var jObject in pars)
{
if (jObject.GetType().Name.ToString() == "JValue") paramElement.ParamName = ((JValue)jObject).ToString();
else
{
paramElement.ParamBody = jObject.ToObject<ParamClass>();
}
}
GateIoTicker gateIoTicker = new GateIoTicker { Params = new List<ParamElement>() };
gateIoTicker.Id = (string)jsonObject["Id"];
gateIoTicker.Method = (string)jsonObject["method"];
gateIoTicker.Params.Add(paramElement);
return gateIoTicker;
}
}
public partial class ParamElement
{
public string ParamName { get; set; }
public ParamClass ParamBody {get; set;}
}
thanks again for the suggestions and nudges. seasons greetings
Try this, it was tested in Visual studio
var jsonObject = JObject.Parse(json);
var pars = jsonObject["params"] as JArray;
var paramElement = new ParamElement();
foreach (var jObject in pars)
{
if (jObject.GetType().Name.ToString() == "JValue") paramElement.ParamName = ((JValue)jObject).ToString();
else
{
paramElement.ParamBody=jObject.ToObject<ParamClass>();
}
}
GateIoTicker gateIoTicker = new GateIoTicker {Params= new List<ParamElement>()};
gateIoTicker.Id= (string) jsonObject["Id"];
gateIoTicker.Method= (string) jsonObject["method"];
gateIoTicker.Params.Add(paramElement);
ParamElement class
public partial class ParamElement
{
public string ParamName { get; set; }
public ParamClass ParamBody {get; set;}
}
So i'm getting a response like this
{"$id":"1","success":true,"errors":{"$id":"2","$values":[]}}
how can i convert this into to a c# object, tried using this(http://json2csharp.com/) tool to make an output but it doesn't make sense
this is what i'm getting
x
public class Errors
{
public string __invalid_name__$id { get; set; }
public List<object> __invalid_name__$values { get; set; }
}
public class RootObject
{
public string __invalid_name__$id { get; set; }
public bool success { get; set; }
public Errors errors { get; set; }
}
I'm kinda new to c#, any inputs would be deeply appreciated, i basically need access to success key variable
You need to add [JsonProperty] attribute to every property that key name started with dollar $
public class Errors
{
[JsonProperty("$id")]
public string id { get; set; }
[JsonProperty("$values")]
public List<object> values { get; set; }
}
public class RootObject
{
[JsonProperty("$id")]
public string id { get; set; }
public bool success { get; set; }
public Errors errors { get; set; }
}
Because the $ indicates metadata, not an actual data field. so you have to modify your JsonSerializerSettings to ignore MetadataPropertyHandling.
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
And finally deserialize your json to above class objects.
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(json, settings);
Here I created a sample console app for demonstration purpose that shows how above code will work.
class program
{
public static void Main()
{
string json = File.ReadAllText(#"Path to your json file");
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(json, settings);
Console.WriteLine("id: " + rootObject.id);
Console.WriteLine("success: " + rootObject.success);
Console.WriteLine("errors.id: " + rootObject.errors.id);
Console.WriteLine("errors.values: " + string.Join(",", rootObject.errors.values));
Console.ReadLine();
}
}
Output:
Well, What you can do is
public class Errors
{
[JsonProperty(PropertyName = "$id")]
public string id { get; set; }
[JsonProperty(PropertyName = "$values")]
public List<object> values { get; set; }
}
public class RootObject
{
[JsonProperty(PropertyName = "$id")]
public string id { get; set; }
public bool success { get; set; }
public Errors errors { get; set; }
}
You need your object attributes to match you json string ($id instead of _invalid_name_$id), then you can use:
JsonConvert.DeserializeObject<RootObject>(jsonString);
Here is a simple class to serialize json string from object or to object (T). May de/serialize array(list) of objects.
public class HelperSerializer<T> where T: class
{
public static string WriteFromObject(T source)
{
using (var ms = new MemoryStream()) {
var ser = new DataContractJsonSerializer(typeof(T));
ser.WriteObject(ms, source);
byte[] json = ms.ToArray();
return Encoding.UTF8.GetString(json, 0, json.Length);
}
}
// Deserialize a JSON stream to an object.
public static T ReadToObject(string json)
{
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var ser = new DataContractJsonSerializer(typeof(T));
return ser.ReadObject(ms) as T;
}
}
}
Use persons = HelperSerializer<List<Person>>.ReadToObject(json);
and var json = HelperSerializer<List<Person>>.WriteFromObject(persons);
using Telerik.Newtonsoft.Json;
MVC Controller:
public ActionResult Index()
{
string responseStr = GetJSON();
var jObject = JsonConvert.DeserializeObject<TheViewModel>(responseStr);
if (jObject == null)
{
return Content("");
}
return View("Default", jObject);
}
Temporary hard coded JSON method:
public string GetJSON() //to be replaced after testing
{
string json = #"{
'name': 'Trial 11.7',
'id': 2599,
'version': '11.7',
'product_id': '1040',
'time_of_execution': '2017-08-07T22:15:38.000Z',
'site_url': 'http://something.com/',
'mc_gem': '11.7',
'suite_gem': '11.7',
'passing_percentage': 95.65,
'failing_percentage': 4.35
}";
return json;
}
The model:
public class TheViewModel
{
public class RootObject
{
public string name { get; set; }
public int id { get; set; }
public string version { get; set; }
public string product_id { get; set; }
public string time_of_execution { get; set; }
public string site_url { get; set; }
public string mc_gem { get; set; }
public string suite_gem { get; set; }
}
}
The problem is that I get the following as the value when I step through the code:
jObject {Master.Project.Mvc.Models.TheViewModel} Master.Project.Mvc.Models.TheViewModel
For some reason I am not getting the JSON deserialized into the object. It is probably something simple, but I am not seeing it.
I receive no error message to help determine the issue inside the controller.
Any help would be appreciated.
You're trying to convert the JSON to an object of type TheViewModel when it's looking for a type of RootObject
You can fix this by either moving all of the fields in RootObject out and into TheViewModel or by calling ...DeserializeObject<TheViewMode.RootObject>(responseStr);
Refactor your code, extract the 'RootObject' class to its own file (or move it so that it is not defined under a class.) will solve the problem.
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>();
I need to deserialize the following:
{"result":{"success":true,"value":"8cb2237d0679ca88db6464eac60da96345513964"}}
to a C# object using Newtonsoft.Json
WebClient wc = new WebClient();
var json = wc.DownloadString(url);
Worker w = JsonConvert.DeserializeObject<Worker>(json);
Here is the class code:
public class Worker
{
[JsonProperty("success")]
public string success { get; set; }
[JsonProperty("value")]
public string value { get; set; }
}
The code does not error out, but the success and value are null.
You're missing the outer object.
public class Worker
{
[JsonProperty("result")]
public Result Result { get; set; }
}
public class Result
{
[JsonProperty("success")]
public string Success { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
You don't need any class and can make use of dynamic keyword
string json = #"{""result"":{""success"":true,""value"":""8cb2237d0679ca88db6464eac60da96345513964""}}";
dynamic dynObj = JsonConvert.DeserializeObject(json);
Console.WriteLine("{0} {1}", dynObj.result.success, dynObj.result.value);
I'm not familiar with that library, but success and result look to be both properties of the object "result"
Have you tried [JsonProperty("result.success")]?
Edit: Well, regardless it looks like a scoping issue. After viewing the documentation, this is my new suggestion:
public class Result{
[JsonProperty("result")]
public Worker result { get; set; }
}
then Json.Convert.Deserialize<Result>(json) instead.