NewtonSoft JsonConvert SerializeObject Dictionary of Object Escape Chars - c#

I'm having some trouble using the JsonConvert.SerializeObject method concerning escape chars in WCF. My web method returns a Stream as follows:
return new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(myObject)));
This works fine apart from one of the properties of myObject is a Dictionary of <string, object>. All of the simple types serialize correctly, however when I try and add my custom class as a value I get the type returned instead of the data. On realising this comes from the serialiser calling .ToString on my custom class I've tried overriding it with:
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
However the returned data now includes escape chars
{
"my_dictionary": {
"elem_1": "{\"Prop1\":null,\"Prop2\":3}",
"elem_2": "{\"Prop1\":null,\"Prop2\":3}",
"int_property" : 123
}
}
Any ideas on how I could avoid my custom class being escaped in this way and returned as an array?
Thanks in advance, Matt

I use JavaScriptSerializer (just replace "Object" with your custom class)
using System.Web.Script.Serialization;
List<Object> list = new List<Object>();
JavaScriptSerializer jss = new JavaScriptSerializer();
string res = jss.Serialize(list);
and get this format with "res" value:
[{"IdEmpresa":1,"Nombre":"Test","URL":"http:/localhost:8080/","Activo":true},IdEmpresa":2,"Nombre":"Test2,","URL":"http://localhost:8081/","Activo":true}]

I've realised there was a mistake in the code. The class that was being serialised actually returned a Dictionary the conversion of the object to a string was causing the behaviour I'd observed and in reality the serializer was perfectly able to serialise the objects correctly.

Related

C# Serializing an objects into JSON but retain the name

So I'm trying to serialize a Dictionary:
Dictionary<string, List<MyClass>>
My class contains a property called MyPropery
However the string comes out as "{"List1":[{"MyProperty":[]}]}"
How would I be able to make it convert to {"List1":["MyClass":{"MyProperty":[]}]}
To achieve what you want, you would need something like:
var obj = new Dictionary<string, List<Dictionary<string, MyClass>>>();
As kalimag pointed out, ["attr": "value"] isn't a valid JSON. The serialization of the object obj, illustrated above, could yield something like:
{"List1": [{"MyClass": {"MyProperty": []}}]}
Which is a valid JSON.

Validate object using json schema in C#

I'm trying to use a json shema to validate an incoming objet parameter in a C# api.
Here is my api proto :
void BuildSqlQueryFromSegment(JoinDefinition jsonDef);
JsonDefinition is a complex objects, with lots of properties. Properties values are depending each other, this is why simple validateur attribute like Required, Min, Max can't be used here.
One solution would be to pass a string instead of the type object :
void BuildSqlQueryFromSegment(string jsonDef) {
// Check shema here, using Json.NET Schema
// if ok, deserialize and get the JsonDefition object instance
}
I'm able to implment this quite easily, but i find this solution not smart.
What i'm looking for is something like this :
void BuildSqlQueryFromSegment([SchemaValidation('MySchemaResourceHere')] JoinDefinition jsonDef);
Does this kind of attribute exist ? If not, how can i implement it ? How can i act on incoming response json string to check the schema ?
Thanks for your help.
First you need to create JsonSchema from JoinDefinition class
JsonSchemaGenerator schemaGenerator = new JsonSchemaGenerator{ };
var o = new JoinDefinition ();
JsonSchema Objschema = schemaGenerator.Generate(o.GetType());
than get Jsonschema from string
JObject jObject= JObject.Parse(JsonString);
bool valid = jObject.IsValid(Objschema);
If JsonString schema match from class json schema it would return true else false
You will have to use below namespace
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;

Parse the JSON string in the ASP.NET

I mostly work on the PHP , recently have switched to ASP.NET,
When parse the JSON, I can simply use -> to get the field, e.g.
foreach(json_decode($_POST['mandrill_events']) as $event) {
$event = $event->event;
$email_type = $event->msg->metadata->email_type;
}
However, in ASP.NET , there is no action, this is my attempt code
var post_data = Request.Form["mandrill_events"];
JavaScriptSerializer ser = new JavaScriptSerializer();
var post_data_json = ser.Deserialize<Dictionary<string, string>>(post_data);
foreach (var event_obj in post_data_json) {
//how to parse the event_obj?
}
Thanks a lot for helping.
use Newtonsoft Json.NET
JsonConvert.DeserializeObject<DataModel>(json);
Unless you want to write a C# class that represents the JSON you are POSTing (the safest solution), you can use the dynamic type to create an object which will look like your JSON. You can then do something like this answer to access the properties.
This solution doesn't give you type safety and the DLR will resolve the properties of the dynamic object at runtime.
As other answers have mentioned, your life will be made much easier by using Newtonsoft JSON which will allow you to write:
dynamic events = JsonConvert.DeserializeObject<dynamic>(post_data);
foreach(dynamic evt in events)
{
string emailType = evt.msg.metadata.email_type;
}

How to receive JSON data into Web API ApiController method?

I'm writing a Web API ApiController with several PUT methods that receive JSON data. The JSON is not deterministic and hence cannot be hard-mapped to a custom C# object, but needs to be received as Dictionaries/Sequences (Maps/Lists).
I have tried using an IDictionary for the data parm of the PUT method in the controller, and this sort of works -- the data appears to be mapped from JSON to the dictionary. However, it's necessary to declare the dictionary as <String,Object>, and there's no clear way to then retrieve the Object values as their appropriate types. (I've found a few suggested kluges in my searching, but they are just that.)
There is also a System.Json.JsonObject type which I finally managed to get loaded via NuGet, but when I use that the system does not appear to know how to map the data.
How is this typically done? How do you implement an ApiController method that receives generic JSON?
I can see three basic approaches:
Somehow make Dictionary/Sequence work with Object or some such.
Make something like System.Json.JsonObject work, perhaps by swizzling the routing info.
Receive the JSON as a byte array and then parse explicitly using one of the C# JSON toolkits available.
(As to how dynamic the data is, JSON objects may have missing entries or extraneous entries, and in some cases a particular entry may be represented as either a single JSON value or a JSON array of values. (Where "value" is JSON array, object, string, number, Boolean, or null.) In general, except for the array/not array ambiguity, the relation between keys and value types is known.)
(But I should note that this is a large project and I'll be receiving JSON strings from several other components by other authors. Being able to examine the received type and assert that it's as expected would be quite useful, and may even be necessary from a security standpoint.)
(I should add that I'm a relative novice with C# -- have only been working with it for about 6 months.)
You've got to know what kind of data you're expecting, but I have had success doing this in the past using dynamic typing.
Something like this:
[Test]
public void JsonTester()
{
string json = "{ 'fruit':'banana', 'color':'yellow' }";
dynamic data = JsonConvert.DeserializeObject(json);
string fruit = data["fruit"];
string color = data["color"];
Assert.That(fruit == "banana");
Assert.That(color == "yellow");
}
Edit:
You either need to know the type you want to deserialize to beforehand - in which case you can deserialize it to that type immediately.
Or you can deserialize it to a dynamic type, and then convert it to your static type once you know what you want to do with it.
using Newtonsoft.Json;
using NUnit.Framework;
public class DTO
{
public string Field1;
public int Field2;
}
public class JsonDeserializationTests
{
[Test]
public void JsonCanBeDeserializedToDTO()
{
string json = "{ 'Field1':'some text', 'Field2':45 }";
var data = JsonConvert.DeserializeObject<DTO>(json);
Assert.That(data.Field1 == "some text");
Assert.That(data.Field2 == 45);
}
[Test]
public void JsonCanBeDeserializedToDynamic_AndConvertedToDTO()
{
string json = "{ 'Field1':'some text', 'Field2':45 }";
var dynamicData = JsonConvert.DeserializeObject<dynamic>(json);
var data = new DTO { Field1 = dynamicData["Field1"], Field2 = dynamicData["Field2"] };
Assert.That(data.Field1 == "some text");
Assert.That(data.Field2 == 45);
}
}

Turn a JSON string into a dynamic object

I'm trying to create a dynamic object from a JSON string in C#. But i can't get it done.
Normally i would get a JSON string through a web service call but in this case I simply created a simple class which I turn into a JSON string. Then I try to turn it back into a dynamic object with the exact same structure as if it was an instance of the Entity class. But that's where I'm having trouble.
This is the class that i turn into a JSON string:
public class Entity
{
public String Name = "Wut";
public String[] Scores = {"aaa", "bbb", "ccc"};
}
Then in somewhere in my code i do this:
var ent = new Entity();
// The Serialize returns this:
// "{\"Name\":\"Wut\",\"Scores\":[\"aaa\",\"bbb\",\"ccc\"]}"
var json = new JavaScriptSerializer().Serialize(ent);
dynamic dynamicObject1 = new JavaScriptSerializer().DeserializeObject(json);
dynamic dynamicObject2 = Json.Decode(json);
When I debug this code then i see that the first dynamicObject1 returns a Dictionary. Not really what I'm after.
The second dynamicObject2 looks more like the Entity object. It has a property called Name with a value. It also has a dynamic array called Scores, but for some reason that list turns out to be empty...
Screenshot of empty Scores property in dynamic object:
So I'm not having any luck so far trying to cast a JSON string to a dynamic object. Anyone any idea how I could get this done?
Using Json.Net
dynamic dynamicObject1 = JsonConvert.DeserializeObject(json);
Console.WriteLine(dynamicObject1.Name);
Using Json.Net but deserializing into a ExpandableOBject, a type that is native to C#:
dynamic obj= JsonConvert.DeserializeObject<ExpandoObject>(yourjson);
If the target type is not specified then it will be convert to JObject type instead. Json object has json types attached to every node that can cause problems when converting the object into other dynamic type like mongo bson.

Categories