Author: atsushi
Date: 2008-01-22 01:50:55 -0500 (Tue, 22 Jan 2008)
New Revision: 93479
Modified:
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonWriter.cs
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/ChangeLog
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/JsonWriterTest.cs
Log:
2008-01-22 Atsushi Enomoto <[EMAIL PROTECTED]>
* JsonWriter.cs : allow __type attribute. It required couple of
changes all around the class.
* DataContractJsonSerializer.cs : implemented large part of
serialization support (deserialization is not done yet).
* JsonWriterTest.cs : added test for writing __type attribute.
* DataContractJsonSerializerTest.cs : added more random-ish tests.
Modified:
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog
===================================================================
---
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog
2008-01-22 05:22:52 UTC (rev 93478)
+++
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog
2008-01-22 06:50:55 UTC (rev 93479)
@@ -1,3 +1,10 @@
+2008-01-22 Atsushi Enomoto <[EMAIL PROTECTED]>
+
+ * JsonWriter.cs : allow __type attribute. It required couple of
+ changes all around the class.
+ * DataContractJsonSerializer.cs : implemented large part of
+ serialization support (deserialization is not done yet).
+
2007-12-05 Atsushi Enomoto <[EMAIL PROTECTED]>
* DataContractJsonSerializer.cs :
Modified:
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs
===================================================================
---
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs
2008-01-22 05:22:52 UTC (rev 93478)
+++
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs
2008-01-22 06:50:55 UTC (rev 93479)
@@ -26,9 +26,12 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Globalization;
using System.IO;
+using System.Reflection;
using System.Text;
using System.Xml;
@@ -36,7 +39,7 @@
{
public sealed class DataContractJsonSerializer : XmlObjectSerializer
{
- DataContractSerializer impl;
+ const string default_root_name = "root";
#region lengthy constructor list
@@ -46,7 +49,7 @@
}
public DataContractJsonSerializer (Type type, IEnumerable<Type>
knownTypes)
- : this (type, "root", Type.EmptyTypes)
+ : this (type, default_root_name, Type.EmptyTypes)
{
}
@@ -56,47 +59,58 @@
}
public DataContractJsonSerializer (Type type,
XmlDictionaryString rootName)
- : this (type, rootName, Type.EmptyTypes)
+ : this (type, rootName != null ? rootName.Value :
default_root_name, Type.EmptyTypes)
{
}
public DataContractJsonSerializer (Type type, string rootName,
IEnumerable<Type> knownTypes)
- : this (type, new XmlDictionary ().Add (rootName),
knownTypes)
+ : this (type, rootName, knownTypes, int.MaxValue,
false, null, true)
{
}
- [MonoTODO]
public DataContractJsonSerializer (Type type,
XmlDictionaryString rootName, IEnumerable<Type> knownTypes)
+ : this (type, rootName != null ? rootName.Value :
default_root_name, knownTypes)
{
- impl = new DataContractSerializer (type, rootName,
XmlDictionaryString.Empty, knownTypes);
- root = rootName;
}
- [MonoTODO]
public DataContractJsonSerializer (Type type, IEnumerable<Type>
knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject,
IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation)
+ : this (type, default_root_name, knownTypes,
maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate,
alwaysEmitTypeInformation)
{
- //impl = new DataContractSerializer (type, knownTypes,
maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate,
alwaysEmitTypeInformation);
- throw new NotImplementedException ();
}
[MonoTODO]
public DataContractJsonSerializer (Type type, string rootName,
IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool
ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool
alwaysEmitTypeInformation)
{
-// impl = new DataContractSerializer (type, rootName,
String.Empty, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject,
dataContractSurrogate, alwaysEmitTypeInformation);
- throw new NotImplementedException ();
+ if (type == null)
+ throw new ArgumentNullException ("type");
+ if (rootName == null)
+ throw new ArgumentNullException ("rootName");
+ if (maxItemsInObjectGraph < 0)
+ throw new ArgumentOutOfRangeException
("maxItemsInObjectGraph");
+
+ List<Type> types = new List<Type> ();
+ types.Add (type);
+ if (knownTypes != null)
+ types.AddRange (knownTypes);
+
+ this.type = type;
+ known_types = new ReadOnlyCollection<Type> (types);
+ root = rootName;
+ max_items = maxItemsInObjectGraph;
+ ignore_extension = ignoreExtensionDataObject;
+ surrogate = dataContractSurrogate;
+ always_emit_type = alwaysEmitTypeInformation;
}
- [MonoTODO]
public DataContractJsonSerializer (Type type,
XmlDictionaryString rootName, IEnumerable<Type> knownTypes, int
maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate
dataContractSurrogate, bool alwaysEmitTypeInformation)
+ : this (type, rootName != null ? rootName.Value : null,
knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject,
dataContractSurrogate, alwaysEmitTypeInformation)
{
-// impl = new DataContractSerializer (type, rootName,
XmlDictionaryString.Empty, knownTypes, maxItemsInObjectGraph,
ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation);
- throw new NotImplementedException ();
}
#endregion
Type type;
- XmlDictionaryString root;
+ string root;
ReadOnlyCollection<Type> known_types;
int max_items;
bool ignore_extension;
@@ -105,126 +119,384 @@
[MonoTODO]
public IDataContractSurrogate DataContractSurrogate {
-// get { return surrogate; }
- get { return impl.DataContractSurrogate; }
+ get { return surrogate; }
}
[MonoTODO]
public bool IgnoreExtensionDataObject {
-// get { return ignore_extension; }
- get { return impl.IgnoreExtensionDataObject; }
+ get { return ignore_extension; }
}
[MonoTODO]
public ReadOnlyCollection<Type> KnownTypes {
-// get { return known_types; }
- get { return impl.KnownTypes; }
+ get { return known_types; }
}
- [MonoTODO]
public int MaxItemsInObjectGraph {
-// get { return max_items; }
- get { return impl.MaxItemsInObjectGraph; }
+ get { return max_items; }
}
- [MonoTODO]
public override bool IsStartObject (XmlReader reader)
{
- return impl.IsStartObject (reader);
+ if (reader == null)
+ throw new ArgumentNullException ("reader");
+ reader.MoveToContent ();
+ return reader.IsStartElement (root, String.Empty);
}
- [MonoTODO]
public override bool IsStartObject (XmlDictionaryReader reader)
{
- return impl.IsStartObject (reader);
+ return IsStartObject ((XmlReader) reader);
}
- [MonoTODO]
public override object ReadObject (Stream stream)
{
return ReadObject
(JsonReaderWriterFactory.CreateJsonReader (stream, new
XmlDictionaryReaderQuotas ()));
}
- [MonoTODO]
public override object ReadObject (XmlDictionaryReader reader)
{
- return impl.ReadObject (reader);
+ return ReadObject (reader, true);
}
- [MonoTODO]
public override object ReadObject (XmlReader reader)
{
- return impl.ReadObject (reader);
+ return ReadObject (reader, true);
}
- [MonoTODO]
public override object ReadObject (XmlDictionaryReader reader,
bool verifyObjectName)
{
- return impl.ReadObject (reader, verifyObjectName);
+ return ReadObject ((XmlReader) reader,
verifyObjectName);
}
[MonoTODO]
public override object ReadObject (XmlReader reader, bool
verifyObjectName)
{
- return impl.ReadObject (reader, verifyObjectName);
+ if (reader == null)
+ throw new ArgumentNullException ("reader");
+ if (verifyObjectName && !IsStartObject (reader))
+ throw new SerializationException (String.Format
("Expected element was '{0}', but the actual input element was '{1}' in
namespace '{2}'", root, reader.LocalName, reader.NamespaceURI));
+
+ throw new NotImplementedException ();
}
- [MonoTODO]
public override void WriteObject (Stream stream, object graph)
{
WriteObject (JsonReaderWriterFactory.CreateJsonWriter
(stream), graph);
}
- [MonoTODO]
public override void WriteObject (XmlWriter writer, object
graph)
{
- impl.WriteObject (writer as XmlDictionaryWriter ??
XmlDictionaryWriter.CreateDictionaryWriter (writer), graph);
- }
-
- [MonoTODO]
- public override void WriteObject (XmlDictionaryWriter writer,
object graph)
- {
try {
- impl.WriteObject (writer, graph);
+ WriteStartObject (writer, graph);
+ WriteObjectContent (writer, graph);
+ WriteEndObject (writer);
+ } catch (NotImplementedException) {
+ throw;
+ } catch (InvalidDataContractException) {
+ throw;
} catch (Exception ex) {
throw new SerializationException (String.Format
("There was an error during serialization for object of type {0}", graph !=
null ? graph.GetType () : null), ex);
}
}
- [MonoTODO]
+ public override void WriteObject (XmlDictionaryWriter writer,
object graph)
+ {
+ WriteObject ((XmlWriter) writer, graph);
+ }
+
public override void WriteStartObject (XmlDictionaryWriter
writer, object graph)
{
- impl.WriteStartObject (writer, graph);
+ WriteStartObject ((XmlWriter) writer, graph);
}
- [MonoTODO]
public override void WriteStartObject (XmlWriter writer, object
graph)
{
- impl.WriteStartObject (writer, graph);
+ if (writer == null)
+ throw new ArgumentNullException ("writer");
+ writer.WriteStartElement (root);
}
- [MonoTODO]
public override void WriteObjectContent (XmlDictionaryWriter
writer, object graph)
{
- impl.WriteObjectContent (writer, graph);
+ WriteObjectContent ((XmlWriter) writer, graph);
}
[MonoTODO]
public override void WriteObjectContent (XmlWriter writer,
object graph)
{
- impl.WriteObjectContent (writer, graph);
+ new Outputter (this, writer, type,
always_emit_type).WriteObjectContent (graph, true, false);
}
- [MonoTODO]
public override void WriteEndObject (XmlDictionaryWriter writer)
{
- impl.WriteEndObject (writer);
+ WriteEndObject ((XmlWriter) writer);
}
- [MonoTODO]
public override void WriteEndObject (XmlWriter writer)
{
- impl.WriteEndObject (writer);
+ if (writer == null)
+ throw new ArgumentNullException ("writer");
+ writer.WriteEndElement ();
}
}
+
+ class Outputter
+ {
+ DataContractJsonSerializer serializer;
+ XmlWriter writer;
+ int serialized_object_count;
+ bool always_emit_type;
+ Dictionary<Type, TypeMap> typemaps = new Dictionary<Type,
TypeMap> ();
+ Type root_type;
+
+ public Outputter (DataContractJsonSerializer serializer,
XmlWriter writer, Type rootType, bool alwaysEmitTypeInformation)
+ {
+ this.serializer = serializer;
+ this.writer = writer;
+ this.root_type = rootType;
+ this.always_emit_type = alwaysEmitTypeInformation;
+ }
+
+ public XmlWriter Writer {
+ get { return writer; }
+ }
+
+ public void WriteObjectContent (object graph, bool top, bool
outputTypeName)
+ {
+ if (graph == null) {
+ if (top)
+ GetTypeMap (root_type); // to make sure
to reject invalid contracts
+ return;
+ }
+
+ if (serialized_object_count ++ ==
serializer.MaxItemsInObjectGraph)
+ throw new SerializationException (String.Format
("The object graph exceeded the maximum object count '{0}' specified in the
serializer", serializer.MaxItemsInObjectGraph));
+
+ switch (Type.GetTypeCode (graph.GetType ())) {
+ case TypeCode.String:
+ writer.WriteString ((string) graph);
+ break;
+ case TypeCode.Single:
+ case TypeCode.Double:
+ case TypeCode.Decimal:
+ if (always_emit_type)
+ writer.WriteAttributeString ("type",
"number");
+ writer.WriteString (((IFormattable)
graph).ToString ("R", CultureInfo.InvariantCulture));
+ break;
+ case TypeCode.Byte:
+ case TypeCode.SByte:
+ case TypeCode.Int16:
+ case TypeCode.Int32:
+ case TypeCode.Int64:
+ case TypeCode.UInt16:
+ case TypeCode.UInt32:
+ case TypeCode.UInt64:
+ if (always_emit_type)
+ writer.WriteAttributeString ("type",
"number");
+ if (graph.GetType ().IsEnum)
+ graph = ((IConvertible) graph).ToType
(Enum.GetUnderlyingType (graph.GetType ()), CultureInfo.InvariantCulture);
+ writer.WriteString (((IFormattable)
graph).ToString ("G", CultureInfo.InvariantCulture));
+ break;
+ case TypeCode.Boolean:
+ if ((bool) graph)
+ writer.WriteString ("true");
+ else
+ writer.WriteString ("false");
+ break;
+ default:
+ if (graph is ICollection) { // array
+ writer.WriteAttributeString ("type",
"array");
+ foreach (object o in (ICollection)
graph) {
+ writer.WriteStartElement
("item");
+ // when it is typed, then no
need to output "__type"
+ WriteObjectContent (o, false,
!(graph is Array && graph.GetType ().GetElementType () != typeof (object)));
+ writer.WriteEndElement ();
+ }
+ } else { // object
+ TypeMap tm = GetTypeMap (graph.GetType
());
+ if (tm != null) {
+ // FIXME: I'm not sure how it
is determined whether __type is written or not...
+ if (outputTypeName)
+
writer.WriteAttributeString ("__type", FormatTypeName (graph.GetType ()));
+ if (always_emit_type)
+
writer.WriteAttributeString ("type", "object");
+ tm.Serialize (this, graph);
+ }
+ else
+ // it does not emit
type="object" (as the graph is regarded as a string)
+// writer.WriteString
(graph.ToString ());
+throw new InvalidDataContractException (String.Format ("Type {0} cannot be
serialized by this JSON serializer", graph.GetType ()));
+ }
+ break;
+ }
+ }
+
+ string FormatTypeName (Type type)
+ {
+ return type.Namespace == null ? type.Name :
String.Format ("{0}:#{1}", type.Name, type.Namespace);
+ }
+
+ TypeMap GetTypeMap (Type type)
+ {
+ TypeMap map;
+ if (!typemaps.TryGetValue (type, out map)) {
+ map = TypeMap.CreateTypeMap (type);
+ typemaps [type] = map;
+ }
+ return map;
+ }
+ }
+
+ class TypeMap
+ {
+ static bool IsInvalidNCName (string name)
+ {
+ if (name == null || name.Length == 0)
+ return true;
+ try {
+ XmlConvert.VerifyNCName (name);
+ } catch (XmlException) {
+ return true;
+ }
+ return false;
+ }
+
+ public static TypeMap CreateTypeMap (Type type)
+ {
+ object [] atts = type.GetCustomAttributes (typeof
(DataContractAttribute), true);
+ if (atts.Length == 1)
+ return CreateTypeMap (type,
(DataContractAttribute) atts [0]);
+
+ atts = type.GetCustomAttributes (typeof
(SerializableAttribute), false);
+ if (atts.Length == 1)
+ return CreateTypeMap (type, null);
+
+ return null;
+ }
+
+ static TypeMap CreateTypeMap (Type type, DataContractAttribute
dca)
+ {
+ if (dca != null && dca.Name != null && IsInvalidNCName
(dca.Name))
+ throw new InvalidDataContractException
(String.Format ("DataContractAttribute for type '{0}' has an invalid name",
type));
+
+ List<TypeMapMember> members = new List<TypeMapMember>
();
+
+ foreach (FieldInfo fi in type.GetFields
(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
+ if (dca != null) {
+ object [] atts = fi.GetCustomAttributes
(typeof (DataMemberAttribute), true);
+ if (atts.Length == 0)
+ continue;
+ DataMemberAttribute dma =
(DataMemberAttribute) atts [0];
+ members.Add (new TypeMapField (fi,
dma));
+ } else {
+ if (fi.GetCustomAttributes (typeof
(NonSerializedAttribute), false).Length > 0)
+ continue;
+ members.Add (new TypeMapField (fi,
null));
+ }
+ }
+
+ if (dca != null) {
+ foreach (PropertyInfo pi in type.GetProperties
(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
+ if (pi.GetIndexParameters ().Length > 0)
+ continue;
+ if (!pi.CanRead || !pi.CanWrite)
+ throw new
InvalidDataContractException (String.Format ("Property {0} must have both
getter and setter", pi));
+ object [] atts = pi.GetCustomAttributes
(typeof (DataMemberAttribute), true);
+ if (atts.Length == 0)
+ continue;
+ DataMemberAttribute dma =
(DataMemberAttribute) atts [0];
+ members.Add (new TypeMapProperty (pi,
dma));
+ }
+ }
+
+ members.Sort (delegate (TypeMapMember m1, TypeMapMember
m2) { return m1.Order - m2.Order; });
+ return new TypeMap (type, dca == null ? null :
dca.Name, members.ToArray ());
+ }
+
+ Type type;
+ string element;
+ TypeMapMember [] members;
+
+ public TypeMap (Type type, string element, TypeMapMember []
orderedMembers)
+ {
+ this.type = type;
+ this.element = element;
+ this.members = orderedMembers;
+ }
+
+ public void Serialize (Outputter outputter, object graph)
+ {
+ foreach (TypeMapMember member in members) {
+ object memberObj = member.GetMemberOf (graph);
+ // FIXME: consider EmitDefaultValue
+ outputter.Writer.WriteStartElement
(member.Name);
+ outputter.WriteObjectContent (memberObj, false,
false);
+ outputter.Writer.WriteEndElement ();
+ }
+ }
+ }
+
+ abstract class TypeMapMember
+ {
+ MemberInfo mi;
+ DataMemberAttribute dma;
+
+ protected TypeMapMember (MemberInfo mi, DataMemberAttribute dma)
+ {
+ this.mi = mi;
+ this.dma = dma;
+ }
+
+ public string Name {
+ get { return dma == null ? mi.Name : dma.Name ??
mi.Name; }
+ }
+
+ // FIXME: Fill 3.5 member in s.r.serialization.
+// public bool EmitDefaultValue {
+// get { return dma != null && dma.EmitDefaultValue; }
+// }
+
+ public bool IsRequired {
+ get { return dma != null && dma.IsRequired; }
+ }
+
+ public int Order {
+ get { return dma != null ? dma.Order : -1; }
+ }
+
+ public abstract object GetMemberOf (object owner);
+ }
+
+ class TypeMapField : TypeMapMember
+ {
+ FieldInfo field;
+
+ public TypeMapField (FieldInfo fi, DataMemberAttribute dma)
+ : base (fi, dma)
+ {
+ this.field = fi;
+ }
+
+ public override object GetMemberOf (object owner)
+ {
+ return field.GetValue (owner);
+ }
+ }
+
+ class TypeMapProperty : TypeMapMember
+ {
+ PropertyInfo property;
+
+ public TypeMapProperty (PropertyInfo pi, DataMemberAttribute
dma)
+ : base (pi, dma)
+ {
+ this.property = pi;
+ }
+
+ public override object GetMemberOf (object owner)
+ {
+ return property.GetValue (owner, null);
+ }
+ }
}
Modified:
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonWriter.cs
===================================================================
---
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonWriter.cs
2008-01-22 05:22:52 UTC (rev 93478)
+++
trunk/olive/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonWriter.cs
2008-01-22 06:50:55 UTC (rev 93479)
@@ -51,7 +51,7 @@
WriteState state;
Stack<ElementType> element_kinds = new Stack<ElementType> ();
Stack<bool> first_content_flags = new Stack<bool> ();
- string attr_value;
+ string attr_name, attr_value, runtime_type;
public JsonWriter (Stream stream, Encoding encoding, bool
closeOutput)
{
@@ -249,12 +249,13 @@
if (!String.IsNullOrEmpty (prefix))
throw new ArgumentException ("Non-empty prefix
is not allowed in this XmlDictionaryWriter");
- if (localName != "type")
- throw new ArgumentException ("Only 'type'
attribute is allowed in this XmlDictionaryWriter");
+ if (localName != "type" && localName != "__type")
+ throw new ArgumentException ("Only 'type' and
'__type' are allowed as an attribute name in this XmlDictionaryWriter");
if (state != WriteState.Element)
throw new InvalidOperationException
(String.Format ("Attribute cannot be written in {0} mode", state));
+ attr_name = localName;
state = WriteState.Attribute;
}
@@ -265,32 +266,36 @@
if (state != WriteState.Attribute)
throw new XmlException ("Cannot close
attribute, as this XmlDictionaryWriter is not at attribute state");
- switch (attr_value) {
- case "object":
- element_kinds.Pop ();
- element_kinds.Push (ElementType.Object);
- output.Write ('{');
- break;
- case "array":
- element_kinds.Pop ();
- element_kinds.Push (ElementType.Array);
- output.Write ('[');
- break;
- case "number":
- element_kinds.Pop ();
- element_kinds.Push (ElementType.Number);
- break;
- case "boolean":
- element_kinds.Pop ();
- element_kinds.Push (ElementType.Boolean);
- break;
- case "string":
- element_kinds.Pop ();
- element_kinds.Push (ElementType.String);
- break;
- default:
- throw new XmlException (String.Format
("Unexpected type attribute value '{0}'", attr_value));
+ if (attr_name == "type") {
+ switch (attr_value) {
+ case "object":
+ element_kinds.Pop ();
+ element_kinds.Push (ElementType.Object);
+ output.Write ('{');
+ break;
+ case "array":
+ element_kinds.Pop ();
+ element_kinds.Push (ElementType.Array);
+ output.Write ('[');
+ break;
+ case "number":
+ element_kinds.Pop ();
+ element_kinds.Push (ElementType.Number);
+ break;
+ case "boolean":
+ element_kinds.Pop ();
+ element_kinds.Push
(ElementType.Boolean);
+ break;
+ case "string":
+ element_kinds.Pop ();
+ element_kinds.Push (ElementType.String);
+ break;
+ default:
+ throw new XmlException (String.Format
("Unexpected type attribute value '{0}'", attr_value));
+ }
}
+ else
+ runtime_type = attr_value;
state = WriteState.Element;
attr_value = null;
@@ -307,6 +312,15 @@
output.Write ('"');
first_content_flags.Push (true);
+
+ if (runtime_type != null) {
+ output.Write ("\"__type\":\"");
+ output.Write (runtime_type);
+ output.Write ('\"');
+ runtime_type = null;
+ first_content_flags.Pop ();
+ first_content_flags.Push (false);
+ }
}
public override void WriteString (string text)
Modified:
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/ChangeLog
===================================================================
---
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/ChangeLog
2008-01-22 05:22:52 UTC (rev 93478)
+++
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/ChangeLog
2008-01-22 06:50:55 UTC (rev 93479)
@@ -1,3 +1,8 @@
+2008-01-22 Atsushi Enomoto <[EMAIL PROTECTED]>
+
+ * JsonWriterTest.cs : added test for writing __type attribute.
+ * DataContractJsonSerializerTest.cs : added more random-ish tests.
+
2007-12-05 Atsushi Enomoto <[EMAIL PROTECTED]>
* DataContractJsonSerializerTest.cs :
Modified:
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs
===================================================================
---
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs
2008-01-22 05:22:52 UTC (rev 93478)
+++
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs
2008-01-22 06:50:55 UTC (rev 93479)
@@ -906,7 +906,24 @@
}
[Test]
+ public void MaxItemsInObjectGraph1 ()
+ {
+ // object count == maximum
+ DataContractJsonSerializer s = new
DataContractJsonSerializer (typeof (DCEmpty), null, 1, false, null, false);
+ s.WriteObject (XmlWriter.Create (TextWriter.Null), new
DCEmpty ());
+ }
+
+ [Test]
[ExpectedException (typeof (SerializationException))]
+ public void MaxItemsInObjectGraph2 ()
+ {
+ // object count > maximum
+ DataContractJsonSerializer s = new
DataContractJsonSerializer (typeof (DCSimple1), null, 1, false, null, false);
+ s.WriteObject (XmlWriter.Create (TextWriter.Null), new
DCSimple1 ());
+ }
+
+ [Test]
+ [ExpectedException (typeof (SerializationException))]
public void DeserializeEnumByName ()
{
// enum is parsed into long
@@ -974,13 +991,36 @@
}
[Test]
- public void ReadObjectVerifyObjectName ()
+ public void ReadObjectVerifyObjectNameFalse ()
{
- string xml = @"<any><Member1
xmlns=""http://schemas.datacontract.org/2004/07/MonoTests.System.Runtime.Serialization"">bar</Member1></any>";
- new DataContractJsonSerializer (typeof
(VerifyObjectNameTestData))
+ string xml = @"<any><Member1>bar</Member1></any>";
+ object o = new DataContractJsonSerializer (typeof
(VerifyObjectNameTestData))
.ReadObject (XmlReader.Create (new StringReader
(xml)), false);
+ Assert.IsTrue (o is VerifyObjectNameTestData, "#1");
+
+ string xml2 = @"<any><x:Member1
xmlns:x=""http://schemas.datacontract.org/2004/07/MonoTests.System.Runtime.Serialization"">bar</x:Member1></any>";
+ o = new DataContractJsonSerializer (typeof
(VerifyObjectNameTestData))
+ .ReadObject (XmlReader.Create (new StringReader
(xml2)), false);
+ Assert.IsTrue (o is VerifyObjectNameTestData, "#2");
}
+ [Test]
+ [ExpectedException (typeof (SerializationException))]
+ public void ReadObjectVerifyObjectNameTrue ()
+ {
+ string xml = @"<any><Member1>bar</Member1></any>";
+ new DataContractJsonSerializer (typeof
(VerifyObjectNameTestData))
+ .ReadObject (XmlReader.Create (new StringReader
(xml)), true);
+ }
+
+ [Test] // member name is out of scope
+ public void ReadObjectVerifyObjectNameTrue2 ()
+ {
+ string xml = @"<root><Member2>bar</Member2></root>";
+ new DataContractJsonSerializer (typeof
(VerifyObjectNameTestData))
+ .ReadObject (XmlReader.Create (new StringReader
(xml)), true);
+ }
+
private object Deserialize (string xml, Type type)
{
DataContractJsonSerializer ser = new
DataContractJsonSerializer (type);
@@ -988,6 +1028,15 @@
return ser.ReadObject (xr);
}
+ [Test]
+ public void IsStartObject ()
+ {
+ DataContractJsonSerializer s = new
DataContractJsonSerializer (typeof (DCSimple1));
+ Assert.IsTrue (s.IsStartObject (XmlReader.Create (new
StringReader ("<root></root>"))), "#1");
+ Assert.IsFalse (s.IsStartObject (XmlReader.Create (new
StringReader ("<dummy></dummy>"))), "#2");
+ Assert.IsFalse (s.IsStartObject (XmlReader.Create (new
StringReader ("<Foo></Foo>"))), "#3");
+ Assert.IsFalse (s.IsStartObject (XmlReader.Create (new
StringReader ("<root xmlns='urn:foo'></root>"))), "#4");
+ }
}
public enum Colors {
Modified:
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/JsonWriterTest.cs
===================================================================
---
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/JsonWriterTest.cs
2008-01-22 05:22:52 UTC (rev 93478)
+++
trunk/olive/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/JsonWriterTest.cs
2008-01-22 06:50:55 UTC (rev 93479)
@@ -468,10 +468,20 @@
w.WriteAttributeString ("type", "object");
w.WriteStartElement (String.Empty);
// It is regarded as invalid name in JSON. However,
- // I don't think there is such specification in JSON.
+ // I don't think there is such limitation in JSON
specification.
}
[Test]
+ public void WriteStartElementWithRuntimeTypeName ()
+ {
+ w.WriteStartElement ("root");
+ w.WriteAttributeString ("type", "object");
+ w.WriteAttributeString ("__type",
"FooType:#FooNamespace");
+ w.Close ();
+ Assert.AreEqual
(@"{""__type"":""FooType:#FooNamespace""}", ResultString);
+ }
+
+ [Test]
public void WriteStartElementWeirdName ()
{
w.WriteStartElement ("root");
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches