Parse Json into a schema-generated set of classes - c#

I have a Json schema and can use NJsonSchema.CodeGeneration.CSharp to create classes corresponding to it. So if I have json which conforms to the schema, I should be able to easily parse it into a collection of objects whose classes are the classes generated from the schema?
So how can I do this - parse json and get out C# class objects that correspond to the objects in the json (as define by the schema)?
As an example - if the schema defines a first object definition which is an array of a second object definition, then I would like to be able to parse it in such a way that the output is an instance of the class corresponding to the first object definition and it has a member which is a List of instances of the class corresponding to the second definition. It seems that the schema knows all the information required to do this, so it should be a single line - I appreciate I could do long-hand parsing (eg converting each item in the array) to achieve the same result.
I would think this would be a primary purpose of having C# classes generated from a schema, so what's the magic method I'm missing?
I'm also happy to write C# classes and generate a schema from that if it's a more workable solution.
I've used NJsonSchema but happy to use any other C# json schema and code generation technique that achieves the same end.
UPDATE: After discussion I've seen that if NJsonSchema is used to generate classes from the schema, the TypeScript version of those classes each have a fromJS method which sounds like what I want but they're missing from the C# version. I'm happy to use something other than NJsonSchema to generate classes from schema if it provides a solution.

I think I found the answer, which was a lot simpler than I had anticipated. It's simply to use something like:
var ob=JsonConvert.DeserializeObject<MyNamespace.Anonymous>(jsonString);
...where MyNamespace is the namespace of the generated C# classes, MyNamespace.Anonymous is the class corresponding to the root of the schema (default names from NJsonSchema), and jsonString the string to be parsed.
I thought the solution would need to be schema-aware, since it would need to know about all the classes created from the schema, but I guess it 'works that out' from reflecting on the Anonymous class it's given and where the properties of it are classes, reflecting on those and so on.
I was over-thinking the problem!

Related

How to create C# Classes during runtime, and access them during the same runtime?

The user will be giving schema information during runtime, and then data which follows the schema.
For instance:
asked for class name => Person.
asked for number of attributes => 2.
asked for attribute with data types => Name, string; Age, integer.
This should create a class in C# as:
class Person
{
string Name;
int Age;
}
Then asked for data- Abc,25; Def,30.
So it creates 2 objects of type Person.
The template class would already be there in the project, the attributes and data will be given during runtime, and during the same runtime the objects are created of that class.
I have tried Text Template Transformation Toolkit (T4), and used their design templates, but it takes the schema information during design time, via accessing a xml config file, and creates the classes.
Then data is given during runtime.
Is there anyway to give even the schema information during runtime?
T4 also has runtime templates, but from my understanding, that generates text files to be used outside the context of the C# project, whereas design time templates can be used to give C# classes to be used in same project. Correct me if I am wrong.
There is a functionality to create dynamic class objects. Here is the MSDN link for the same.
Also. a tutorial to understand the creation of the dynamic classes with required properties during run time
as far as i know you cannot instantiate a class like that, a clas must be defined.
but you can create a dynamic class (type safety is gone) and assign the properties then the values.
you can also generate a json and deselialize it to a dynamic calss like in this answer

Xml Serialisation

Does anyone know if there is an alternative to using attributes on C# properties to map to XML nodes when using XmlSerializer?
My issue is that I have an object called Article, with some properties (e.g. ID, Title, Body) and I do not want to add attributes directly to it (used elsewhere, etc, etc)...so I created a partial class and re-defined the properties and added the attributes there, but soon discovered that you cannot have duplicate properties in partial classes.
So I was wondering if anyone knew of any way that I could map the properties instead (in a similar fashion to n-hibernate, for example).
I'd appreciate any help.
There's a constructor of the XmlSerializer class that allows you to pass a XmlAttributeOverrides and thus alter the behavior at runtime.
Quote from the documentation:
The overrides parameter can be used to control how fields and
properties are encoded in XML. These settings override any attributes
that already exist on the objects. This can be useful when the source
code cannot be modified or multiple encodings are required for the
same classes.
You could implement IXmlSerializable directly. It requires some more code, but you will have full control without the need for attributes.

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.

How can i fill my custom classes properties with an xml file?

My program creates xslt files and stores the information from custom classes there, this is done dynamically with attributes which mark the classes and properties I want to store in the xslt. This was quite easy because i just had to name the attribute like the property and fill the value with the object's toString() method.
Now I want to somehow reload that Information, create the same classes and fill the properties with those values. But how do i do that with e.g. Enums and other complex types if i don't know the type at compile time? Has to be some sort of parse method..
Any ideas?
If you just want to serialize your objects to XML and then desterilize them, and your objects contain interfaces, generic lists or other complex type you can use very useful serialization library http://www.codeproject.com/KB/XML/sharpserializer.aspx by Pawel Idzikowski.
It is really straight forward and can be very helpful in such cases.

xsd.exe generated classes don't serialize default value attributes

I have few .cs files generated by xsd.exe by a XSD schema.
My problem is that when i try to serialize those classes to xml, the attributes whose values match the default values defined in the xsd schema are not being serialized.
I found out that my problem is solved when i remove [System.ComponentModel.DefaultValueAttribute(typeof(<someType>), "<SomeValue>")]
attribute for the member representing a default field.
So my question isn't there more elegant way to do this? For example is there any way to specify that I want the default values to be serialized anyway?
The short versions is: yes. it looks like that is the simplest approach.
I've tried the "obvious" things (in particular the *Specified and ShouldSerialize* patterns that XmlSerializer supports, but also IsNullable) and it just keeps on not including the value.
The next options would be either IXmlSerializable (which is plain hard), or XmlAttributeOverrides (a duplication of effort) - neither of which is particularly enticing here. I wonder if your current approach is less work? You could of course simply export the WSDL and edit that to remove the default (and generate from the edited version).
As an aside - if this was WCF, there is the [DataMember(EmitDefaultValue = ...)] that does control this; maybe they added this as a feature request?

Categories

Resources