How can I make XmlSerializer.Deserialize more strict? - c#

I have some very similar XML structures which are in fact quite distinct, but it appears that XmlSerializer.Deserialize is very "forgiving" and will go out of its way to take XML and deserialize out into a strongly typed object I created from the source XSDs. Is there any way to make it more strict or do some type of deeper validation?
// Locals
var serializer = new XmlSerializer(typeof(SomeCustomType));
// Set
var someInstance = serializer.Deserialize(new StringReader(xmlString.ToString()))
#Jeff Because the root nodes are similar it will deserialize into completely different objects. Imagine that you have a house, car and boat and they all share a base root node called item with a few attributes. Even though sub-nodes are invalid and unshared it seems to overlook and forgive that.
#Will I don't want to validate against the XSD. I want to somehow cause the Deserializer to see that the data it has shouldn't be shoe-horned into the wrong Object type.

The problem was that the XML input was incorrect.

I once used validating reader to validate XML against schema as I read it into the deserializer.

Related

Smart way of changing json conversion to xml and keep setup

I have already deserialized a json-file to c#-objects. This has been done by the following:
JsonSerializer<FooClass>().DeserializeFromString(json)
and it all works well. I now want to change the json to xml and do the exact same, keeping all the classes and setup, that has already been made inside the solution.
The conversion from json to xml is easy, but I cant figure out how to deserialize the xml so that I dont need to change a lot of code.
Is it possible to keep the whole setup, but somehow change few lines of code such as
JsonSerializer<FooClass>().DeserializeFromString(json)
to something alike, but that deserializes the xml instead?
I've found the following solutions in here, but they don't seem to solve the problem:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
but the SerializeXmlNode isn't possible?
The other solutions I have found in here use arguments and stuff like that, which again will force me to change some of the setup, which I am not interested in, if possible.
Also I am aware, that a direct transformation from json to xml has its cons, but if we look aside from that and focus on the xml part, then it would be nice.
This because we are writing in xml instead of json from now on and therefore the change needed.
One easy route I can see is to leverage the XmlClass Attributes and use XmlSerializer.

How to ensure that the class library represents the Json Schema perfectly

I have a JSON Schema, and a class library.
I am able to serialize this class, then convert back successfully to object.
To test it, I create a random object, serialize it.
Then convert to object and check its validity.
And deserialize it just to be sure about the values.
The code below works perfectly - but
I want to be absolutely sure that the class library represents the Json Schema.
Is there a way to achieve this? I found some online tools tries to create the class library from given schema, but none of them were so useful.
// Create random object.
MyObject myObject = new MyObject().CreateRandomMyObject();
// Serialize it.
string JSONObjectText = JsonConvert.SerializeObject(myObject);
// Check if schema is valid.
JSchema schema = JSchema.Parse(txtSchema.Value);
// Check if the serialized object is valid for schema.
JObject jsonObject = JObject.Parse(JSONObjectText);
IList<string> errorMessages;
bool valid = jsonObject.IsValid(schema, out errorMessages);
// Check if the serialized object can be deserialized.
MyObject myObjectReDeserialized = (MyObject)JsonConvert.DeserializeObject(JSONObjectText, typeof(MyObject), new JsonSerializerSettings() { MissingMemberHandling = MissingMemberHandling.Error });
A way to do test-oriented assertion of your mapping is to use FsCheck to generate plenty of random objects and then assert what you want to hold from them: in this case, that
their serialization is valid given the schema,
they can be deserialized back to the same object. (You should make sure you are using structural equality there.)
To be precise, such approach only checks that everything described by your objects is representable by the schema. You might want to do the other way also -- that every JSON that conforms to the schema is representable by your objects. Again, you can generate many possible JSONs conforming to the schema and check that
they can be deserialized to your objects,
reserialization of those objects gives you the same JSON you started with.
Beware though, this might not be practical: FsCheck probably don't have some nice, first-class support for JSON schema based generation out-of-the-box.
If the schema you have is going to change in the future, it would be really great to have a way to generate corresponding objects to have strong types even at the boundary of your application. Have you tried Swagger Codegen? Swagger describes it's endpoints using subset of JSON Schema. The corresponding tooling might help you.

How can I deserialize data from xml and how can I create classes dynamically by xml element name?

I have a dynamic XML structure. I mean, root name can be changed, element name can be changed and structure of xml can be changed.So How can I deserialize dynamic xml to objects?
Creating classes dynamically by xml element names, is this possible? If yes, then how can I do this?
So How can I deserialize this type xml to objects?
Well, you cannot deserialize a XML without a specific XSD schema to statically typed classes. You could use a XDocument or XmlReader classes to parse and extract information from it.
If you're using .Net 4, the ExpandoObject might be what you need:
Represents an object whose members can be dynamically added and removed at run time.
You want to look into the factory pattern. The basic idea is:
for each XML node, get the type name / name of node
ask factory for type with given name
create object of the given type
pass the XML node to object to allow it to load its data
XSD schemas help here to verify the XML is structurally correct although not necessary. I did try this once, creating objects from XML, but I never found a way to have multiple schema files for one XML (this would have allowed me to extend the schema without changing the root schema, if you see what I mean).

Deserialize XML with different schemas into a shared type

Using c#, I want to deserialize xml from various sources into objects of a common type. The XML will not have the same schema. Eg, in the following xml, /thingContainer/thing/name and widget/#title both would map to myClass.DisplayName.
Xml1:
<thingContainer>
<thing>
<name>MyName</name>
</thing>
</thingContainer>
Xml2:
<widget title="myTitle" />
So, I can't mark up my class with [XmlElement], since it will be different depending on the source of my xml. Is there some trick I can do with inheritance or some helper class that will enable me to easily deserialize xml from different sources? Is there some easy way to map class fields to xpaths?
Of course, if I have to, I'll parse and manually deserialize the xml... but what fun is that?
Two thoughts that immediately spring to mind:
Use XSLT to transform the original XML into an interim format that matches your object model (a very popular approach, though personally I despise XSL)
Create interim object models to deserialize to, then map them to your final object model.
There's probably some XmlElement hackery possible, but it seems like it would be a messy approach.
I think you have two options here:
Implement IXmlSerializable for your class and deserialize taking into account the structure of your XML
Just use LINQ to XML to parse the XML and create an instance of your class. This is the approach I would pick (having gone through the first choice myself and not liking it)

Write CLR objects to XML with LINQ

I have an ObservableCollection items. I want to convert these to XML format so that I can store them for later use. I'm a little new to LINQ and I'm not sure how to do this. I know that I need to rely on the XDocument. But I'm not sure how to execute the query and get the results into a string format.
Can somebody please provide some pointers for me? It just seems like such an easy task, I'd be surprised if it couldn't be done.
Thank you,
You need Linq to XML. I can't post a real code here since I don't know the structure of your data, but here's a dummy example:
List<Person> people = ...
var doc = new XDocument(
new XElement("People",
from p in people
select new XElement("Person",
new XAttribute("Id", p.Id),
new XElement("LastName", p.LastName),
new XElement("FistName", p.FirstName))));
doc.Save("people.xml");
Note that Linq is not the only option here. Another very good approach is XML serialization.
Using the DataContractSerializer is your best bet. It's designed to do exactly what you are asking for.
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer(v=VS.95).aspx
Advantages over XMLSerializer:
Opt-in rather than opt-out properties to serialize. This mean you specify what you want serialize
Because it is opt in you can serialize not only properties, but also fields. You can even serialize non-public members such as private or protected members. And you dont need a set on a property either (however without a setter you can serialize, but not deserialize)
Is about 10% faster than XmlSerializer to serialize the data because since you don’t have full control over how it is serialize, there is a lot that can be done to optimize the serialization/deserialization process.
Can understand the SerializableAttribute and know that it needs to be serialized
More options and control over KnownTypes
Disadvantages:
No control over how the object is serialized outside of setting the name and the order
I'm not sure what you want.
You can create a XElement and convert it to a string with the ToString method.
You can do the same with XDocument.
I'm not at all familiar with Silverlight, but it sounds like you are going to need to use XML serialization. XML serialization allows you to serialize an object into an XML representation, which you can then later deserialize from XML back into an object.
Here are some tutorials and information on XML serialization in .NET:
XML Serialization
XML Serialization Using C#
XmlSerializer class

Categories