Microsoft provides lots of different ways to encode HTML and URIs, but their newest library, called AntiXSS, is the best of the bunch.
Has anyone found a good pattern for serialization without deserialization?
In my previous post about mixing serialization, I mentioned that we’d implemented the IXmlSerializable interface in many of our classes. The main reason for doing this was to include elements and attributes that were read-only.
In other words, we wanted additional information to appear in the serialized stream. This additional information is not needed in order to rehydrate the object.
Most serialization frameworks don’t handle this case. After all, if the point of serialization is to transport an object across the wire, cluttering up the stream with extra information is wasteful. Besides, you can’t dictate what someone on the other side might do with the data. Nicholas Allen discusses this point in his post explaining why read-only data members are not supported in WCF.
While I understand his point from an object remoting perspective, the reason for choosing XML as a data format in the first place was to allow for human readability. What if you want to embed metadata in your XML that doesn’t affect the behavior of the object? You’d need to include it in the XML output, but you aren’t interested reading it back in from an XML stream. What’s the best way to achieve this?
For example, in our data layer we have a Version object that brings together information about when the object was created and by whom, when it was modified and by whom, as well as the object’s revision number. It’s useful to have this information in resulting XML string, but we don’t need to read it back in.
So here’s my question: Are we doing this wrong? Does the need for one-way serialization indicate a problem with our object model? Is it a code smell, or is it simply an edge case not considered by existing frameworks?
Who doesn’t like mixing their Raisin Flakes with their Oaty-O’s in the morning? Yum! But it’s not a good idea if you’re talking about serial formats in C# 3.5 instead of breakfast cereals. You’ll get output that might leave a bad taste in your mouth.
Question: You’re writing a web API for an application. To give developers the most flexibility in interacting with your system, you want to expose classes that can be serialized to either XML or JSON. Using WCF and C# 3.5 SP1, what are your options?
Answer: There’s only one option unless you rely on 3rd party serialization libraries. You must mark the class with the [DataContract] attribute and mark each serializable member with [DataMember]. This allows you to serialize and deserialize using the DataContractSerializer and DataContractJsonSerializer for XML and JSON respectively.
I mention this because we’d gone to great lengths to customize our XML using the IXmlSerializable interface. This gave us fine control over the properties we wanted to appear in our XML output and how they were formatted. But if you use the IXmlSerializable interface, you can’t also annotate the class with the [DataContract] attribute. You’ll get a compiler error. Sowmy Srinivasan explains this serialization restriction.
I know what you’re thinking: If the framework provides an IXmlSerializable interface, isn’t there also an IJsonSerializable interface? Sadly, no. There’s no way to fine-tune the JSON output. Sigh.
So, if you’re currently using IXmlSerializable, you can forget about the DataContractJsonSerializer. Or you can accept that you’re fighting the framework, forget about your fancy-pants XML format, and accept the default serialization, keeping these data member best practices in mind.
Infovark has too much invested in our XML layout at this point. We’ve built our XSD files, XSL Transforms, and many, many unit tests. So we gave up on the DataContractJsonSerializer and turned to the excellent JSON.NET, written by James Newton-King. It’s now version 3.0 and fully supports the new LINQ constructs.
It’s a little more work, but we think it’s worth it.
James Newton-King, developer of the JSON.NET project, notes that it gets harder to be a .NET developer with every release. He reposted a chart from Brad Abrams showing the growth of the number of types in the Microsoft .NET framework.
We’ve run into this problem all the time developing infovark. Often, it’s not the sheer size of the framework that proves challenging, but finding just the right method to do just the right thing.
A case in point was a recent problem I had in converting a DateTime object into a string properly formatted for XML. Normally you’d do something like this:
string theDateString = myDateTime.ToString();
This gives you a string in the .NET format, but that’s not the correct format for XML Schema (XSD). No problem, you think, I’ll just pass a format argument to the ToString method. So you look up the available string formatting options on MSDN. There’s lots of choices here, from the “based on ISO 8601″ format to the “RFC1123Pattern” to the “UniversalSortableDateTimePattern”. But it turns out that none of these formats work for XML if you want it to validate against your XML Schema. What gives? Do you have to provide a custom formatting string to get the date pattern you want?
It turns out that you’re looking in the wrong place entirely. These aren’t the string formats you’re looking for. Move along.
What you want is in the System.Xml namespace. You want the XmlConvert class. The XmlConvert class lets you convert from native .NET types to valid XML and back. The code looks like this:
string theDateString = XmlConvert.ToString(myDateTime);
It’s not only the size of the .NET framework that’s daunting. It’s the fact that functionality can be duplicated — or worse — made just slightly different across all of those classes. It puts developers in an awkward situation. Do they spend time researching to figure out exactly which method of which class in which namespace ought to be used in a given situation? Or do they roll their own (possibly buggy) implementation? It’s a tough call.
Personally, I’d like to see more guidance from Microsoft — perhaps through their code analysis tools — as to the preferred way of doing common tasks.