-Added GetSchema, CanRead, CanWrite to JsonConverter
-Fix CustomCreationConverter erroring when writing JSON
This commit is contained in:
+1
-1
@@ -18,7 +18,7 @@
|
||||
)
|
||||
}
|
||||
|
||||
task default -depends Build
|
||||
task default -depends Test
|
||||
|
||||
task Clean {
|
||||
Set-Location $baseDir
|
||||
|
||||
+2
-1
@@ -1 +1,2 @@
|
||||
powershell -Command "& {Import-Module ..\Tools\PSake\psake.psm1; Invoke-psake .\build.ps1 %*}"
|
||||
powershell -Command "& {Import-Module ..\Tools\PSake\psake.psm1; Invoke-psake .\build.ps1 %*}"
|
||||
pause
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Newtonsoft.Json.Tests.Converters
|
||||
{
|
||||
@@ -87,5 +88,62 @@ namespace Newtonsoft.Json.Tests.Converters
|
||||
Console.WriteLine(employee.JobTitle);
|
||||
// Support
|
||||
}
|
||||
|
||||
public class MyClass
|
||||
{
|
||||
public string Value { get; set; }
|
||||
|
||||
[JsonConverter(typeof(MyThingConverter))]
|
||||
public IThing Thing { get; set; }
|
||||
}
|
||||
|
||||
public interface IThing
|
||||
{
|
||||
int Number { get; }
|
||||
}
|
||||
|
||||
public class MyThing : IThing
|
||||
{
|
||||
public int Number { get; set; }
|
||||
}
|
||||
|
||||
public class MyThingConverter : CustomCreationConverter<IThing>
|
||||
{
|
||||
public override IThing Create(Type objectType)
|
||||
{
|
||||
return new MyThing();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AssertDoesDeserialize()
|
||||
{
|
||||
const string json = @"{
|
||||
""Value"": ""A value"",
|
||||
""Thing"": {
|
||||
""Number"": 123
|
||||
}
|
||||
}
|
||||
";
|
||||
MyClass myClass = JsonConvert.DeserializeObject<MyClass>(json);
|
||||
Assert.IsNotNull(myClass);
|
||||
Assert.AreEqual("A value", myClass.Value);
|
||||
Assert.IsNotNull(myClass.Thing);
|
||||
Assert.AreEqual(123, myClass.Thing.Number);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AssertShouldSerializeTest()
|
||||
{
|
||||
MyClass myClass = new MyClass
|
||||
{
|
||||
Value = "Foo",
|
||||
Thing = new MyThing { Number = 456, }
|
||||
};
|
||||
string json = JsonConvert.SerializeObject(myClass); // <-- Exception here
|
||||
|
||||
const string expected = @"{""Value"":""Foo"",""Thing"":{""Number"":456}}";
|
||||
Assert.AreEqual(expected, json);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#region License
|
||||
// Copyright (c) 2007 James Newton-King
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if !SILVERLIGHT && !PocketPC
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Newtonsoft.Json.Tests.Converters
|
||||
{
|
||||
public class HtmlColorConverterTests : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void WriteJsonTest()
|
||||
{
|
||||
string json;
|
||||
|
||||
json = JsonConvert.SerializeObject(Color.DarkGray, new HtmlColorConverter());
|
||||
Assert.AreEqual(@"""DarkGray""", json);
|
||||
|
||||
json = JsonConvert.SerializeObject(Color.FromArgb(255, 1, 2, 3), new HtmlColorConverter());
|
||||
Assert.AreEqual(@"""#010203""", json);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadJsonTest()
|
||||
{
|
||||
string json = @"""#010203""";
|
||||
|
||||
Color c = JsonConvert.DeserializeObject<Color>(json, new HtmlColorConverter());
|
||||
Assert.AreEqual(c.A, 255);
|
||||
Assert.AreEqual(c.R, 1);
|
||||
Assert.AreEqual(c.G, 2);
|
||||
Assert.AreEqual(c.B, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -62,8 +62,10 @@
|
||||
<Compile Include="Bson\BsonReaderTests.cs" />
|
||||
<Compile Include="Bson\BsonWriterTests.cs" />
|
||||
<Compile Include="Converters\BinaryConverterTests.cs" />
|
||||
<Compile Include="Converters\CustomCreationConverterTests.cs" />
|
||||
<Compile Include="Converters\DataSetConverterTests.cs" />
|
||||
<Compile Include="Converters\DataTableConverterTests.cs" />
|
||||
<Compile Include="Converters\HtmlColorConverterTests.cs" />
|
||||
<Compile Include="Converters\StringEnumConverterTests.cs" />
|
||||
<Compile Include="Linq\ComponentModel\BindingTests.cs" />
|
||||
<Compile Include="Linq\ComponentModel\JPropertyDescriptorTests.cs" />
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml" />
|
||||
@@ -68,6 +69,7 @@
|
||||
<Compile Include="Converters\CustomCreationConverterTests.cs" />
|
||||
<Compile Include="Converters\DataSetConverterTests.cs" />
|
||||
<Compile Include="Converters\DataTableConverterTests.cs" />
|
||||
<Compile Include="Converters\HtmlColorConverterTests.cs" />
|
||||
<Compile Include="Converters\StringEnumConverterTests.cs" />
|
||||
<Compile Include="JsonArrayAttributeTests.cs" />
|
||||
<Compile Include="ExceptionTests.cs" />
|
||||
|
||||
@@ -71,8 +71,10 @@
|
||||
<Compile Include="Bson\BsonReaderTests.cs" />
|
||||
<Compile Include="Bson\BsonWriterTests.cs" />
|
||||
<Compile Include="Converters\BinaryConverterTests.cs" />
|
||||
<Compile Include="Converters\CustomCreationConverterTests.cs" />
|
||||
<Compile Include="Converters\DataSetConverterTests.cs" />
|
||||
<Compile Include="Converters\DataTableConverterTests.cs" />
|
||||
<Compile Include="Converters\HtmlColorConverterTests.cs" />
|
||||
<Compile Include="Converters\StringEnumConverterTests.cs" />
|
||||
<Compile Include="ExceptionTests.cs" />
|
||||
<Compile Include="JsonArrayAttributeTests.cs" />
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
<Reference Include="System.Data.Linq">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Runtime.Serialization">
|
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
@@ -89,6 +90,7 @@
|
||||
<Compile Include="Converters\DataTableConverterTests.cs" />
|
||||
<Compile Include="Converters\DataSetConverterTests.cs" />
|
||||
<Compile Include="Converters\CustomCreationConverterTests.cs" />
|
||||
<Compile Include="Converters\HtmlColorConverterTests.cs" />
|
||||
<Compile Include="Converters\StringEnumConverterTests.cs" />
|
||||
<Compile Include="FileSystemEntityModel.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
|
||||
@@ -79,5 +79,16 @@ namespace Newtonsoft.Json.Converters
|
||||
{
|
||||
return typeof (T).IsAssignableFrom(objectType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,17 @@ namespace Newtonsoft.Json.Converters
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="JsonConverter"/> can read JSON.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this <see cref="JsonConverter"/> can read JSON; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -27,6 +27,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using Newtonsoft.Json.Schema;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
@@ -60,5 +61,32 @@ namespace Newtonsoft.Json
|
||||
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public abstract bool CanConvert(Type objectType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="JsonSchema"/> of the JSON produced by the JsonConverter.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="JsonSchema"/> of the JSON produced by the JsonConverter.</returns>
|
||||
public virtual JsonSchema GetSchema()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="JsonConverter"/> can read JSON.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this <see cref="JsonConverter"/> can read JSON; otherwise, <c>false</c>.</value>
|
||||
public virtual bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.</value>
|
||||
public virtual bool CanWrite
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -432,18 +432,14 @@ namespace Newtonsoft.Json
|
||||
serializerWriter.Serialize(jsonWriter, value);
|
||||
}
|
||||
|
||||
internal bool HasMatchingConverter(Type type, out JsonConverter matchingConverter)
|
||||
internal JsonConverter GetMatchingConverter(Type type)
|
||||
{
|
||||
if (HasMatchingConverter(_converters, type, out matchingConverter))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return GetMatchingConverter(_converters, type);
|
||||
}
|
||||
|
||||
internal static bool HasMatchingConverter(IList<JsonConverter> converters, Type objectType, out JsonConverter matchingConverter)
|
||||
internal static JsonConverter GetMatchingConverter(IList<JsonConverter> converters, Type objectType)
|
||||
{
|
||||
if (objectType == null)
|
||||
throw new ArgumentNullException("objectType");
|
||||
ValidationUtils.ArgumentNotNull(objectType, "objectType");
|
||||
|
||||
if (converters != null)
|
||||
{
|
||||
@@ -452,15 +448,11 @@ namespace Newtonsoft.Json
|
||||
JsonConverter converter = converters[i];
|
||||
|
||||
if (converter.CanConvert(objectType))
|
||||
{
|
||||
matchingConverter = converter;
|
||||
return true;
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
}
|
||||
|
||||
matchingConverter = null;
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
internal void OnError(ErrorEventArgs e)
|
||||
|
||||
@@ -273,7 +273,7 @@ namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
JsonConverter matchingConverter;
|
||||
|
||||
if (value != null && JsonSerializer.HasMatchingConverter(converters, value.GetType(), out matchingConverter))
|
||||
if (value != null && ((matchingConverter = JsonSerializer.GetMatchingConverter(converters, value.GetType())) != null))
|
||||
matchingConverter.WriteJson(writer, value, new JsonSerializer());
|
||||
else
|
||||
defaultWrite(value);
|
||||
|
||||
@@ -234,6 +234,15 @@ namespace Newtonsoft.Json.Schema
|
||||
throw new Exception("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
|
||||
}
|
||||
|
||||
JsonContract contract = ContractResolver.ResolveContract(type);
|
||||
JsonConverter converter;
|
||||
if ((converter = contract.Converter) != null || (converter = contract.InternalConverter) != null)
|
||||
{
|
||||
JsonSchema converterSchema = converter.GetSchema();
|
||||
if (converterSchema != null)
|
||||
return converterSchema;
|
||||
}
|
||||
|
||||
Push(new TypeSchema(type, new JsonSchema()));
|
||||
|
||||
if (explicitId != null)
|
||||
@@ -244,8 +253,7 @@ namespace Newtonsoft.Json.Schema
|
||||
CurrentSchema.Title = GetTitle(type);
|
||||
CurrentSchema.Description = GetDescription(type);
|
||||
|
||||
JsonContract contract = ContractResolver.ResolveContract(type);
|
||||
if (contract.Converter != null || contract.InternalConverter != null)
|
||||
if (converter != null)
|
||||
{
|
||||
// todo: Add GetSchema to JsonConverter and use here?
|
||||
CurrentSchema.Type = JsonSchemaType.Any;
|
||||
|
||||
@@ -204,9 +204,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
contract.Converter = ResolveContractConverter(contract.UnderlyingType);
|
||||
|
||||
// then see whether object is compadible with any of the built in converters
|
||||
JsonConverter internalConverter;
|
||||
if (JsonSerializer.HasMatchingConverter(BuiltInConverters, contract.UnderlyingType, out internalConverter))
|
||||
contract.InternalConverter = internalConverter;
|
||||
contract.InternalConverter = JsonSerializer.GetMatchingConverter(BuiltInConverters, contract.UnderlyingType);
|
||||
|
||||
if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true)
|
||||
|| contract.CreatedType.IsValueType)
|
||||
|
||||
@@ -179,24 +179,29 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
private object CreateValue(JsonReader reader, Type objectType, JsonContract contract, object existingValue, JsonConverter memberConverter)
|
||||
{
|
||||
JsonConverter converter;
|
||||
|
||||
// member attribute converter
|
||||
JsonConverter converter = null;
|
||||
if (memberConverter != null)
|
||||
return memberConverter.ReadJson(reader, objectType, GetInternalSerializer());
|
||||
{
|
||||
// member attribute converter
|
||||
converter = memberConverter;
|
||||
}
|
||||
else if (contract != null)
|
||||
{
|
||||
JsonConverter matchingConverter;
|
||||
if (contract.Converter != null)
|
||||
// class attribute converter
|
||||
converter = contract.Converter;
|
||||
else if ((matchingConverter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null)
|
||||
// passed in converters
|
||||
converter = matchingConverter;
|
||||
else if (contract.InternalConverter != null)
|
||||
// internally specified converter
|
||||
converter = contract.InternalConverter;
|
||||
}
|
||||
|
||||
// class attribute converter
|
||||
if (contract != null && contract.Converter != null)
|
||||
return contract.Converter.ReadJson(reader, objectType, GetInternalSerializer());
|
||||
|
||||
// passed in converters
|
||||
if (objectType != null && Serializer.HasMatchingConverter(objectType, out converter))
|
||||
if (converter != null && converter.CanRead)
|
||||
return converter.ReadJson(reader, objectType, GetInternalSerializer());
|
||||
|
||||
// internally specified converter
|
||||
if (contract != null && contract.InternalConverter != null)
|
||||
return contract.InternalConverter.ReadJson(reader, objectType, GetInternalSerializer());
|
||||
|
||||
if (contract is JsonLinqContract)
|
||||
return CreateJToken(reader, contract);
|
||||
|
||||
|
||||
@@ -90,10 +90,11 @@ namespace Newtonsoft.Json.Serialization
|
||||
return;
|
||||
}
|
||||
|
||||
if (converter != null
|
||||
if ((converter != null
|
||||
|| ((converter = contract.Converter) != null)
|
||||
|| Serializer.HasMatchingConverter(contract.UnderlyingType, out converter)
|
||||
|| ((converter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null)
|
||||
|| ((converter = contract.InternalConverter) != null))
|
||||
&& converter.CanWrite)
|
||||
{
|
||||
SerializeConvertable(writer, converter, value, contract);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user