I have a struct in C# that wraps a guid. I'm using DataContractJsonSerializer to serialize an object containing an instance of that class. When I was using a guid directly, it was serialized as a plain string, but now it's serialized as a name/value pair. Here's an NUnit test and supporting code that demonstrates the problem:
private static string ToJson<T>(T data)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (T));
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, data);
return Encoding.Default.GetString(ms.ToArray());
}
}
[Serializable]
private class ID
{
private Guid _value;
public static explicit operator ID(Guid id)
{
return new ID { _value = id };
}
public static explicit operator Guid(ID id)
{
return id._value;
}
}
[Test]
public void IDShouldSerializeLikeGuid()
{
Guid guid = Guid.NewGuid();
ID id = (ID) guid;
Assert.That(ToJson(id), Is.EqualTo(ToJson(guid)));
}
And the test runner output:
NUnit.Framework.AssertionException: Expected string length 38 but was 49. Strings differ at index 0.
Expected: ""7511fb9f-3515-4e95-9a04-06580753527d""
But was: "{"_value":"7511fb9f-3515-4e95-9a04-06580753527d"}"
-----------^
How do I serialize my struct as a plain string and make my test pass?
NET objects as JSON (serialize) To write JSON to a string or to a file, call the JsonSerializer. Serialize method. The JSON output is minified (whitespace, indentation, and new-line characters are removed) by default.
As the name suggests, deserialization in C# is the reverse process of serialization. It is the process of getting back the serialized object so that it can be loaded into memory. It resurrects the state of the object by setting properties, fields etc. Types. Binary Serialization.
JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).
Serialization. In Serialization, it converts a custom . Net object to a JSON string. In the following code, it creates an instance of BlogSiteclass and assigns some values to its properties. Then we create an instance of JavaScriptSerializer and call Serialize() method by passing object(BlogSites).
In this case it looks like you don't really want JSON, you want a string representation. In that case I would create an interface like this:
interface IStringSerialized
{
String GetString();
}
Implement this interface on your ID
type (and all other types that have similar requirements).
[Serializable]
class ID : IStringSerialized
{
private Guid _value;
public static explicit operator ID(Guid id)
{
return new ID { _value = id };
}
public static explicit operator Guid(ID id)
{
return id._value;
}
public string GetString()
{
return this._value.ToString();
}
}
Then modify your serialization method to handle these special cases:
private static string ToJson<T>(T data)
{
IStringSerialized s = data as IStringSerialized;
if (s != null)
return s.GetString();
DataContractJsonSerializer serializer
= new DataContractJsonSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, data);
return Encoding.Default.GetString(ms.ToArray());
}
}
Try using the JavaScriptSerializer Class it will prevent the key, value bloat issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With