-Fixed generating generic simple type names
-Changed JsonObjectAttribute to be compatible with structs
This commit is contained in:
@@ -203,6 +203,7 @@
|
||||
<Compile Include="TestObjects\VersionKeyedCollection.cs" />
|
||||
<Compile Include="TestObjects\WagePerson.cs" />
|
||||
<Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
|
||||
<Compile Include="Utilities\ReflectionUtilsTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.Compact.csproj">
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
<Compile Include="TestObjects\VersionKeyedCollection.cs" />
|
||||
<Compile Include="TestObjects\WagePerson.cs" />
|
||||
<Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
|
||||
<Compile Include="Utilities\ReflectionUtilsTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
|
||||
|
||||
@@ -214,6 +214,7 @@
|
||||
<Compile Include="TestObjects\VersionKeyedCollection.cs" />
|
||||
<Compile Include="TestObjects\WagePerson.cs" />
|
||||
<Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
|
||||
<Compile Include="Utilities\ReflectionUtilsTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.Silverlight.csproj">
|
||||
|
||||
@@ -249,6 +249,7 @@
|
||||
<Compile Include="TestObjects\TypedSubHashtable.cs" />
|
||||
<Compile Include="TestObjects\UserNullable.cs" />
|
||||
<Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
|
||||
<Compile Include="Utilities\ReflectionUtilsTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.csproj">
|
||||
|
||||
@@ -3506,5 +3506,32 @@ keyword such as type of business.""
|
||||
JsonConvert.DeserializeObject<StringDictionaryTestClass>(json);
|
||||
}
|
||||
#endif
|
||||
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
public struct StructWithAttribute
|
||||
{
|
||||
public string MyString { get; set; }
|
||||
[JsonProperty]
|
||||
public int MyInt { get; set; }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeStructWithJsonObjectAttribute()
|
||||
{
|
||||
StructWithAttribute testStruct = new StructWithAttribute
|
||||
{
|
||||
MyInt = int.MaxValue
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(testStruct, Formatting.Indented);
|
||||
|
||||
Assert.AreEqual(@"{
|
||||
""MyInt"": 2147483647
|
||||
}", json);
|
||||
|
||||
StructWithAttribute newStruct = JsonConvert.DeserializeObject<StructWithAttribute>(json);
|
||||
|
||||
Assert.AreEqual(int.MaxValue, newStruct.MyInt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
public class ReflectionUtilsTests : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void GetTypeNameSimpleForGenericTypes()
|
||||
{
|
||||
string typeName;
|
||||
|
||||
typeName = ReflectionUtils.GetTypeName(typeof(IList<Type>), FormatterAssemblyStyle.Simple);
|
||||
Assert.AreEqual("System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib", typeName);
|
||||
|
||||
typeName = ReflectionUtils.GetTypeName(typeof(IDictionary<IList<Type>, IList<Type>>), FormatterAssemblyStyle.Simple);
|
||||
Assert.AreEqual("System.Collections.Generic.IDictionary`2[[System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib],[System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib]], mscorlib", typeName);
|
||||
|
||||
typeName = ReflectionUtils.GetTypeName(typeof(IList<>), FormatterAssemblyStyle.Simple);
|
||||
Assert.AreEqual("System.Collections.Generic.IList`1, mscorlib", typeName);
|
||||
|
||||
typeName = ReflectionUtils.GetTypeName(typeof(IDictionary<,>), FormatterAssemblyStyle.Simple);
|
||||
Assert.AreEqual("System.Collections.Generic.IDictionary`2, mscorlib", typeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace Newtonsoft.Json
|
||||
/// <summary>
|
||||
/// Instructs the <see cref="JsonSerializer"/> how to serialize the object.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
|
||||
public sealed class JsonObjectAttribute : JsonContainerAttribute
|
||||
{
|
||||
private MemberSerialization _memberSerialization = MemberSerialization.OptOut;
|
||||
|
||||
@@ -161,10 +161,10 @@ namespace Newtonsoft.Json.Linq
|
||||
/// </returns>
|
||||
public override JEnumerable<JToken> Children()
|
||||
{
|
||||
return new JEnumerable<JToken>(ChildrenInternal());
|
||||
return new JEnumerable<JToken>(GetValueEnumerable());
|
||||
}
|
||||
|
||||
private IEnumerable<JToken> ChildrenInternal()
|
||||
private IEnumerable<JToken> GetValueEnumerable()
|
||||
{
|
||||
yield return Value;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
@@ -45,7 +47,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
switch (assemblyFormat)
|
||||
{
|
||||
case FormatterAssemblyStyle.Simple:
|
||||
return t.FullName + ", " + t.Assembly.GetName().Name;
|
||||
return GetSimpleTypeName(t);
|
||||
case FormatterAssemblyStyle.Full:
|
||||
return t.AssemblyQualifiedName;
|
||||
default:
|
||||
@@ -53,6 +55,55 @@ namespace Newtonsoft.Json.Utilities
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetSimpleTypeName(Type type)
|
||||
{
|
||||
string fullyQualifiedTypeName = type.FullName + ", " + type.Assembly.GetName().Name;
|
||||
|
||||
// for type names with no nested type names then return
|
||||
if (!type.IsGenericType || type.IsGenericTypeDefinition)
|
||||
return fullyQualifiedTypeName;
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
// loop through the type name and filter out qualified assembly details from nested type names
|
||||
bool writingAssemblyName = false;
|
||||
bool skippingAssemblyDetails = false;
|
||||
for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
|
||||
{
|
||||
char current = fullyQualifiedTypeName[i];
|
||||
switch (current)
|
||||
{
|
||||
case '[':
|
||||
writingAssemblyName = false;
|
||||
skippingAssemblyDetails = false;
|
||||
builder.Append(current);
|
||||
break;
|
||||
case ']':
|
||||
writingAssemblyName = false;
|
||||
skippingAssemblyDetails = false;
|
||||
builder.Append(current);
|
||||
break;
|
||||
case ',':
|
||||
if (!writingAssemblyName)
|
||||
{
|
||||
writingAssemblyName = true;
|
||||
builder.Append(current);
|
||||
}
|
||||
else
|
||||
{
|
||||
skippingAssemblyDetails = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!skippingAssemblyDetails)
|
||||
builder.Append(current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static bool IsInstantiatableType(Type t)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(t, "t");
|
||||
|
||||
Reference in New Issue
Block a user