-Fixed deserializing byte arrays with type name information

This commit is contained in:
JamesNK
2011-11-01 12:37:47 +00:00
parent c7de25a37a
commit da7e4508d7
8 changed files with 210 additions and 7 deletions
@@ -1214,5 +1214,34 @@ namespace Newtonsoft.Json.Tests.Bson
Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan);
Assert.AreEqual(c1.Uri, c2.Uri);
}
[Test]
public void DeserializeByteArrayWithTypeNameHandling()
{
TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 });
JsonSerializer serializer = new JsonSerializer();
serializer.TypeNameHandling = TypeNameHandling.All;
byte[] objectBytes;
using (MemoryStream bsonStream = new MemoryStream())
using (JsonWriter bsonWriter = new BsonWriter(bsonStream))
{
serializer.Serialize(bsonWriter, test);
bsonWriter.Flush();
objectBytes = bsonStream.ToArray();
}
using (MemoryStream bsonStream = new MemoryStream(objectBytes))
using (JsonReader bsonReader = new BsonReader(bsonStream))
{
// Get exception here
TestObject newObject = (TestObject)serializer.Deserialize(bsonReader);
Assert.AreEqual("Test", newObject.Name);
Assert.AreEqual(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data);
}
}
}
}
@@ -30,6 +30,7 @@ using NUnit.Framework;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Tests.Serialization;
namespace Newtonsoft.Json.Tests.Linq
{
@@ -305,5 +306,30 @@ namespace Newtonsoft.Json.Tests.Linq
ReadAsBytesTestObject x = s.Deserialize<ReadAsBytesTestObject>(new JTokenReader(nullToken));
Assert.IsNull(x.Data);
}
[Test]
public void DeserializeByteArrayWithTypeNameHandling()
{
TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 });
string json = JsonConvert.SerializeObject(test, Formatting.Indented, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
JObject o = JObject.Parse(json);
JsonSerializer serializer = new JsonSerializer();
serializer.TypeNameHandling = TypeNameHandling.All;
using (JsonReader nodeReader = o.CreateReader())
{
// Get exception here
TestObject newObject = (TestObject)serializer.Deserialize(nodeReader);
Assert.AreEqual("Test", newObject.Name);
Assert.AreEqual(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data);
}
}
}
}
@@ -66,5 +66,5 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.0.3.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.0.3.14301")]
[assembly: AssemblyFileVersion("4.0.3.14302")]
#endif
@@ -44,6 +44,7 @@ using System.Collections;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.ObjectModel;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Linq;
using System.Linq;
using Newtonsoft.Json.Converters;
@@ -5015,6 +5016,52 @@ keyword such as type of business.""
Assert.AreEqual(uri, output);
}
[Test]
public void DeserializeByteArrayWithTypeNameHandling()
{
TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 });
JsonSerializer serializer = new JsonSerializer();
serializer.TypeNameHandling = TypeNameHandling.All;
byte[] objectBytes;
using (MemoryStream bsonStream = new MemoryStream())
using (JsonWriter bsonWriter = new JsonTextWriter(new StreamWriter(bsonStream)))
{
serializer.Serialize(bsonWriter, test);
bsonWriter.Flush();
objectBytes = bsonStream.ToArray();
}
using (MemoryStream bsonStream = new MemoryStream(objectBytes))
using (JsonReader bsonReader = new JsonTextReader(new StreamReader(bsonStream)))
{
// Get exception here
TestObject newObject = (TestObject) serializer.Deserialize(bsonReader);
Assert.AreEqual("Test", newObject.Name);
Assert.AreEqual(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data);
}
}
}
public class TestObject
{
public TestObject()
{
}
public TestObject(string name, byte[] data)
{
Name = name;
Data = data;
}
public string Name { get; set; }
public byte[] Data { get; set; }
}
public class UriGuidTimeSpanTestClass
+32
View File
@@ -158,6 +158,14 @@ namespace Newtonsoft.Json.Bson
{
Read();
if (IsWrappedInTypeObject())
{
byte[] data = ReadAsBytes();
Read();
SetToken(JsonToken.Bytes, data);
return data;
}
if (TokenType == JsonToken.Null)
return null;
if (TokenType == JsonToken.Bytes)
@@ -166,6 +174,30 @@ namespace Newtonsoft.Json.Bson
throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
}
private bool IsWrappedInTypeObject()
{
if (TokenType == JsonToken.StartObject)
{
Read();
if (Value.ToString() == "$type")
{
Read();
if (Value != null && Value.ToString().StartsWith("System.Byte[]"))
{
Read();
if (Value.ToString() == "$value")
{
return true;
}
}
}
throw new JsonReaderException("Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
}
return false;
}
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
/// </summary>
+42 -5
View File
@@ -323,6 +323,35 @@ namespace Newtonsoft.Json
return ReadInternal();
}
private bool IsWrappedInTypeObject()
{
_readType = ReadType.Read;
if (TokenType == JsonToken.StartObject)
{
int startObjectLineNumber = _currentLineNumber;
int startObjectLinePosition = _currentLinePosition;
ReadInternal();
if (Value.ToString() == "$type")
{
ReadInternal();
if (Value != null && Value.ToString().StartsWith("System.Byte[]"))
{
ReadInternal();
if (Value.ToString() == "$value")
{
return true;
}
}
}
throw CreateJsonReaderException("Unexpected token when reading bytes: {0}. Line {1}, position {2}.", JsonToken.StartObject, startObjectLineNumber, startObjectLinePosition);
}
return false;
}
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
/// </summary>
@@ -333,11 +362,19 @@ namespace Newtonsoft.Json
{
_readType = ReadType.ReadAsBytes;
do
{
if (!ReadInternal())
throw CreateJsonReaderException("Unexpected end when reading bytes: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
} while (TokenType == JsonToken.Comment);
do
{
if (!ReadInternal())
throw CreateJsonReaderException("Unexpected end when reading bytes: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
} while (TokenType == JsonToken.Comment);
if (IsWrappedInTypeObject())
{
byte[] data = ReadAsBytes();
ReadInternal();
SetToken(JsonToken.Bytes, data);
return data;
}
if (TokenType == JsonToken.Null)
return null;
+32
View File
@@ -38,6 +38,14 @@ namespace Newtonsoft.Json.Linq
{
Read();
if (IsWrappedInTypeObject())
{
byte[] data = ReadAsBytes();
Read();
SetToken(JsonToken.Bytes, data);
return data;
}
// attempt to convert possible base 64 string to bytes
if (TokenType == JsonToken.String)
{
@@ -54,6 +62,30 @@ namespace Newtonsoft.Json.Linq
throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
}
private bool IsWrappedInTypeObject()
{
if (TokenType == JsonToken.StartObject)
{
Read();
if (Value.ToString() == "$type")
{
Read();
if (Value != null && Value.ToString().StartsWith("System.Byte[]"))
{
Read();
if (Value.ToString() == "$value")
{
return true;
}
}
}
throw new JsonReaderException("Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
}
return false;
}
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
/// </summary>
@@ -85,7 +85,7 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.0.3.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.0.3.14301")]
[assembly: AssemblyFileVersion("4.0.3.14302")]
#endif
[assembly: CLSCompliant(true)]