Json.NET Type Conversion - c#

I have two applications which are communicating via rest API, serialized via Json.NET
The part that i am having difficulties with is passing an inheritance structure between the two applications:
ChildClass1 : BaseClass
ChildClass2 : BaseClass
I need to be able to deserialize a list of BaseClasses that have each individually been deserialized into their correct relative type:
JsonConvert.DeserializeObject<IEnumerable<BaseClass>>(json)
I am aware of the TypeNameHandling.All Serializer setting, but the problem i have is that the class on each application are in different namespaces:
Application 1:
App1.NameSpace.ChildClass1
Application 2:
App2.DifferentNameSpace.ChildClass1
Due to this it is not automatically converting them. It is not possible to change the namespaces or use a contract library for these classes.
Do i need to write a custom JsonReader? or is there a setting i can use to override the class name when being serialized / deserialized so that i can remove the namespace?

You can use an ISerializationBinder you set on the settings that allow you to specify the name to use in JSON during serialization and what type to use on deserialization.
That way you have full control over the names to use.
An example can be found here.

Related

Is there any way for my class to support serialisation as an XML attribute?

I have a custom class that only has one property of type string.
Attempting to serialise an object of this class as an attribute using XmlSerializer results in the exception:
XmlAttribute/XmlText cannot be used to encode complex types
Now I know I can fudge this my creating a pseudo string property in my containing type and serialising that instead, but is there any way at all to make my custom class support it intrinsically?
How do .Net classes do it (eg DateTime)?
In order to this you have to implement IXmlSerializable and fully control how your type is serialized / deserialized. Rather overwhelming effort for such an easy task, though. People mostly get stuck with this when it comes to Nullable types.

XMLSerializer: Deserializing as derived type

I've got my fingers crossed that someone out there has a good understanding of the Microsoft XmlSerializer.
Basically, I have built a system for outputting XML on the back of the serializer which is now causing me a lot of hassle and I am trying to avoid a significant re-write.
Introduction
My current system employs a lot of derived classes.
For example,
BaseResponse -> CarParkResponse -> CarParkResponseInherited
BaseResponse and CarParkResponse (both in a library dll) are seperate from CarParkResponseInherited.
As a result, the base classes are ignorent of the derived class.
What I have done
-> Declared derived classes
I appreciate that in order for xmlserializer to do its thing, there are a number of ways to declare dervied classes.
Declare derived classes in base classes using XmlInclude
or
Declared types to be serialised and deserialised in xmlSerialiser. For example:
XmlSerializer serializer = new XmlSerializer(typeof(CarParkResponse), new Type[] { typeof(CarParkParameters), typeof(CarParkInformation) });
I have gone with the latter.
What I am trying to do
Because the derived classes are seperate and they share the same properties, what I am trying to do is serialize the dervied class as the subclass.
In other words deserialize CarParkResponseInherited as a CarParkResponse.
In "CarParkResponseInherited" I am using the declaration XmlTypeAttribute("CarParkResponse").
Initially this causes a problem when serialized
Types 'CarParkResponseInherited' and 'CarParkResponse' both use the XML type name, 'CarParkResponse', from namespace ''. Use XML attributes to specify a unique XML name and/or namespace for the type."
as the type is already in use "CarParkResponse" so I've declased XmlType("Response") in "CarParkResponse" to get around this.
The Problem
I am now trying to Deserialize the XML returned but I'm now getting the following problem.
The specified type was not recognized: name='CarParkResponse', namespace='', at OriginalRequest xmlns=''
Frustratingly the CarParkResponse is there. I am wondering if this is down to the fact I've used XmlType("Response") in the class and the serializer doesn't recognise the class as being type of CarParkResponse
So my question is
Basically is it possible to pass a derived class as a sub class and have it deserialized as the subclass using the XmlSerializer?
I have experimented with the xml produced.
For example, if I don't use the Serialization tags (such as XmlType() etc.) anywhere in my code. The xml produced will produce a carparkresponse element with "type" as an attribute.
The value is "CarParkResponseInherited". I have written some code that removes "Inherited" from the value which does allow it to be deserialized.
This approach is obviously not good so I am hoping there is a good way around this.
So...
if there is anyone out there that has had to patience to read through this post and can help or offer advice it would be most appreciated as I am all out of ideas.
Thanks.
It might be possible to do something using the XmlAttributeOverrides class. It's mostly used for specific property overrides, so it may or may not be the best thing for you.
The long way around would be to go ahead and serialize as the inherited class. Then, if the mappings are the same, deserialize the xml into the base class, and then, re-serialize into what you want.
Depending on how much or how little control you have over the assemblies, you could override the serialization on the inherited class so it does it as the base class.

JSON.NET - exclude properties of a specific type at runtime

I'm wondering how to exclude/strip certain properties of given type(s) (or collections of those) from being serialized using Json.NET library?
I tried to write my own contract resolver (inheriting from DefaultContractResolver) with no luck.
I know that I could be done using DataAnnotations, decorating the excluded properties with ScriptIgnoreAttribute, but it's not applicable in my scenario. The objects serialized can be virtually anything, so I don't know which properties to exclude at design-time. I know only the types of properties that should not be serialized.
It looks like a rather simple task, but unfortunately I couldn't find a decent solution anywhere...
BTW - I'm not bound to Json.NET library - if it can easily be done with default/other .NET JSON serializers it'd be an equally good solution for me.
UPDATE
The properties has to be excluded before trying to serialize them. Why?
Basically, the types of objects I'm receiving and serializing can have dynamic properties of type inheriting from IDynamicMetaObjectProvider. I'm not going to describe all the details, but the DynamicMetaObject returned from GetMetaObject method of these objects doesn't have DynamicMetaObject.GetDynamicMemberNames method implemented (throws NotImplementedException...). Summarizing - the problem is those objects (I need to exclude) doesn't allow to enumerate their properties, what Json.NET serializer tries to do behind the scenes. I always end up with NotImplementedException being thrown.
I have tried both the WCF JSON serialization as well as the System.Web.Script.Serialization.JavaScriptSerializer. I have found if you want solid control of the serialization process and do not want to be bound by attributes and hacks to make things work, the JavaScriptSerializer is the way to go. It is included in the .NET stack and allows you to create and register JavaScriptConverter subclasses to perform custom serialization of types.
The only restriction I have found that may cause you a problem is that you cannot easily register a converter to convert all subclasses of Object (aka, one converter to rule them all). You really need to have knowledge of common base classes or preregister the set of types up front by scanning an assembly. However, property serialization is entirely left up to you, so you can decide using simple reflection which properties to serialize and how.
Plus, the default serialization is much much much better for JSON than the WCF approach. By default, all types are serializable without attributes, enums serialize by name, string-key dictionaries serialize as JSON objects, lists serialize as arrays, etc. But for obvious reasons, such as circular trees, even the default behavior needs assistance from time to time.
In my case, I was supporting a client-API that did not exactly match the server class structure, and we wanted a much simpler JSON syntax that was easy on the eyes, and the JavaScriptSerializer did the trick every time. Just let me know if you need some code samples to get started.
Create your own contract resolver, override the method that creates the properties for an object and then filter the results to only include those that you want.
Have you considered using the ShouldSerialize prefix property to exclude the property of your specific type at runtime?
public class Employee
{
public string Name { get; set; }
public Employee Manager { get; set; }
public bool ShouldSerializeManager()
{
return (Manager != this);
}
}

Designing Classes With Interface In C# (JSON.NET)

I am in the process of designing an itemization system for a game. I am creating a bunch of interfaces (IItem, IConsumable, IEquipable, IWeapon, etc...) to define what type of functionality is possible with items and then a number of classes (Weapon, Potion, etc...) the define the actual item types.
Now when saving out the player, the data is going to be stored as a JSON file (using the JSON.NET library) and will included the players inventory which will include these items. The issue is that when I try to deserialize the JSON file to an object when reading in the file, how will I be able to tell the JSON.NET library what type of class this is?
One thing I thought of and have not had time to try yet is that all my objects that get serialized into JSON have a DTO version of the object that is used in conjunction with the JSON.NET library. What I though about trying is maybe I could add in a property to the DTO called ClassType and then when reading the file into the application, I would first read the object in as an anonymous type. Then based on the ClassType property, I would convert it to the proper type. The 2 issues I have with this is that 1. it seems like a very ugly solution and 2. I am not even sure if that is possible.
(Copied from this question)
In cases here I have not had control over the incoming JSON (and so cannot ensure that it includes a $type property) I have written a custom converter that just allows you to explicitly specify the concrete type:
public class Model
{
[JsonConverter(typeof(ConcreteTypeConverter<Something>))]
public ISomething TheThing { get; set; }
}
This just uses the default serializer implementation from Json.Net whilst explicitly specifying the concrete type.
The source code and an overview are available on this blog post.
You should know the concrete type when you are serializing. So you can use TypeNameHandling of JSON.NET.
http://james.newtonking.com/archive/2010/08/13/json-net-3-5-release-8-3-5-final.aspx?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+jamesnewtonking+%28James+Newton-King%29

JSON serializer and CSLA objects

We just started a new ASP.Net project that uses web services to serialize some CSLA business objects into JSON data for our client javascript/JQuery code. After reviewing the JSON data in the client browser(Firebug in Firefox) we notices that there are a significant number of properties from the business object that we do not need downloaded to the browser.
Is there a way to exclude properties (other than marking them private) from getting serialized by the JSON serializer? We are not calling the JSONSerializer directly, but instead just included a ScriptMethod declaration on the WebMethod.
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
<WebMethod()> _
Public Function getQuestions()
UPDATE
We tried the suggestion of adding the attribute on the public property but received an error:
Error 25 Attribute 'NonSerializedAtrribute' cannot be
applied to 'Name' because the attribute is not valid
on the is declaration type.
Now if we add NonSerialized to the class then it works but not on the property. However, we do want some properties to be serialized.
Any ideas?
You should use ScriptIgnore attribute for all properties which should be not serialized.
If you decide to make more customization of data serialization, for example, replacing one properties name with another one or converting some properties in an array and so on you can write a small JavaScriptTypeResolver which do it.
ScriptIgnore should do the job for you as sugested by Oleg. Check out this link for a detailed sample
you could try to place a NonSerializedAttribute on the properties not sure if it works with the Json serializer...
Edit: if you are using .net 4.0 you could try to use the ISerializable interface...

Categories

Resources