Issue #AR-1_serialization: fix regression error, added AsFieldsetAttribute to help resolve ambiguous complex models, some renaming

This commit is contained in:
cankoluman
2014-04-28 12:45:30 +01:00
parent cbec133186
commit 43e1855b2c
6 changed files with 102 additions and 30 deletions
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Archetype.Umbraco.PropertyConverters;
using Newtonsoft.Json;
using NUnit.Framework;
@@ -42,8 +43,48 @@ namespace Archetype.Tests.Serialization
{
var result = JsonConvert.SerializeObject(_pageDetails, Formatting.Indented);
Assert.AreEqual(JsonTestStrings._PAGE_DETAILS_JSON, result);
}
}
[Test]
public void ConvertComplexModelToArchetype()
{
var converter = new ArchetypeValueConverter();
var json = JsonConvert.SerializeObject(_pageDetails, Formatting.Indented);
var archetype = (Archetype.Umbraco.Models.Archetype)converter.ConvertDataToSource(null, json, false);
Assert.NotNull(archetype);
}
[Test]
public void DeserializeComplexModelFromArchetype()
{
var result = JsonConvert.DeserializeObject<PageDetails>(JsonTestStrings._PAGE_DETAILS_JSON);
Assert.NotNull(result);
Assert.IsInstanceOf<PageDetails>(result);
Assert.AreEqual("2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453", result.Pages);
Assert.AreEqual("First Page", result.Captions.TextStringArray.ElementAt(0));
Assert.AreEqual("Second Page", result.Captions.TextStringArray.ElementAt(1));
Assert.AreEqual("Third Page", result.Captions.TextStringArray.ElementAt(2));
Assert.AreEqual("Fourth Page", result.Captions.TextStringArray.ElementAt(3));
}
[Test]
public void SerializeThenDeserializeComplexModelFromArchetype()
{
var json = JsonConvert.SerializeObject(_pageDetails);
var result = JsonConvert.DeserializeObject<PageDetails>(json);
Assert.NotNull(result);
Assert.IsInstanceOf<PageDetails>(result);
Assert.AreEqual(_pageDetails.Pages, result.Pages);
Assert.AreEqual(_pageDetails.Captions.TextStringArray.ElementAt(0), result.Captions.TextStringArray.ElementAt(0));
Assert.AreEqual(_pageDetails.Captions.TextStringArray.ElementAt(1), result.Captions.TextStringArray.ElementAt(1));
Assert.AreEqual(_pageDetails.Captions.TextStringArray.ElementAt(2), result.Captions.TextStringArray.ElementAt(2));
Assert.AreEqual(_pageDetails.Captions.TextStringArray.ElementAt(3), result.Captions.TextStringArray.ElementAt(3));
}
#endregion
}
@@ -7,7 +7,7 @@ namespace Archetype.Tests.Serialization
{
#region json test Models
[ArchetypeDatatype("urlPicker")]
[AsArchetype("urlPicker")]
[JsonConverter(typeof(ArchetypeJsonConverter<UrlPicker>))]
public class UrlPicker
{
@@ -23,7 +23,7 @@ namespace Archetype.Tests.Serialization
public bool OpenInNewWindow { get; set; }
}
[ArchetypeDatatype("contactDetails")]
[AsArchetype("contactDetails")]
[JsonConverter(typeof(ArchetypeJsonConverter<ContactDetails>))]
public class ContactDetails
{
@@ -43,7 +43,7 @@ namespace Archetype.Tests.Serialization
public UrlPicker WebSite { get; set; }
}
[ArchetypeDatatype("companyDetails")]
[AsArchetype("companyDetails")]
[JsonConverter(typeof(ArchetypeJsonConverter<CompanyDetails>))]
public class CompanyDetails
{
@@ -53,7 +53,7 @@ namespace Archetype.Tests.Serialization
public ContactDetails ContactDetails { get; set; }
}
[ArchetypeDatatype("allContactDetails")]
[AsArchetype("allContactDetails")]
[JsonConverter(typeof(ArchetypeJsonConverter<AllContactDetails>))]
public class AllContactDetails
{
@@ -62,13 +62,13 @@ namespace Archetype.Tests.Serialization
}
[ArchetypeDatatype("contactDetailsList")]
[AsArchetype("contactDetailsList")]
[JsonConverter(typeof(ArchetypeJsonConverter<ContactDetailsList>))]
public class ContactDetailsList : List<ContactDetails>
{
}
[ArchetypeDatatype("annualStatement")]
[AsArchetype("annualStatement")]
[JsonConverter(typeof(ArchetypeJsonConverter<AnnualStatement>))]
public class AnnualStatement
{
@@ -80,7 +80,7 @@ namespace Archetype.Tests.Serialization
public Decimal Profit { get; set; }
}
[ArchetypeDatatype("mergerDetails")]
[AsArchetype("mergerDetails")]
[JsonConverter(typeof(ArchetypeJsonConverter<MergerDetails>))]
public class MergerDetails
{
@@ -93,17 +93,18 @@ namespace Archetype.Tests.Serialization
#region complex nested model
[ArchetypeDatatype("pages")]
[AsArchetype("pages")]
[JsonConverter(typeof(ArchetypeJsonConverter<PageDetails>))]
public class PageDetails
{
[JsonProperty("pages")]
public string Pages { get; set; }
[AsFieldset]
[JsonProperty("captions")]
public Captions Captions { get; set; }
}
[ArchetypeDatatype("captions")]
[AsArchetype("captions")]
[JsonConverter(typeof(ArchetypeJsonConverter<Captions>))]
public class Captions
{
@@ -111,13 +112,13 @@ namespace Archetype.Tests.Serialization
public TextList TextStringArray { get; set; }
}
[ArchetypeDatatype("textstringArray")]
[AsArchetype("textstringArray")]
[JsonConverter(typeof(ArchetypeJsonConverter<TextList>))]
public class TextList : List<TextItem>
{
}
[ArchetypeDatatype("textstringArray")]
[AsArchetype("textstringArray")]
[JsonConverter(typeof(ArchetypeJsonConverter<TextItem>))]
public class TextItem
{
@@ -241,8 +241,9 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\VersionInfo.cs" />
<Compile Include="PropertyConverters\ArchetypeValueConverter.cs" />
<Compile Include="Serialization\ArchetypeDatatypeAttribute.cs" />
<Compile Include="Serialization\AsArchetypeAttribute.cs" />
<Compile Include="Serialization\ArchetypeJsonConverter.cs" />
<Compile Include="Serialization\AsFieldsetAttribute.cs" />
<Compile Include="Serialization\SerializationExtensions.cs" />
</ItemGroup>
<ItemGroup>
@@ -107,23 +107,42 @@ namespace Archetype.Umbraco.Serialization
if (null != models)
return models;
models = GetPropertiesToSerialize(value)
.Select(pInfo =>
{
if (pInfo.PropertyType.IsPrimitive || pInfo.PropertyType.IsValueType
|| pInfo.PropertyType.Name.Equals(typeof(String).Name))
{
var dynamicModel = new ExpandoObject() as IDictionary<string, object>;
dynamicModel.Add(GetJsonPropertyName(pInfo), pInfo.GetValue(value));
return dynamicModel;
}
var properties = GetPropertiesToSerialize(value).ToList();
return pInfo.GetValue(value);
}).ToList();
if (!PropertyLayoutHasFieldsets(properties))
return new List<object>() { value };
var dynamicModel = new ExpandoObject() as IDictionary<string, object>;
foreach (var pInfo in properties.Where(pInfo => !HasAsFieldsetAttribute(pInfo)))
{
dynamicModel.Add(GetJsonPropertyName(pInfo), pInfo.GetValue(value));
}
var fieldsetModels = properties.Where(HasAsFieldsetAttribute)
.Select(pInfo => pInfo.GetValue(value));
models = new List<object>
{
dynamicModel,
};
models = ((IEnumerable<object>)models).Concat(fieldsetModels).ToList();
return models;
}
private bool PropertyLayoutHasFieldsets(IEnumerable<PropertyInfo> properties)
{
return properties.Any(HasAsFieldsetAttribute);
}
private static bool HasAsFieldsetAttribute(PropertyInfo pInfo)
{
return pInfo
.GetCustomAttributes(typeof(AsFieldsetAttribute), true).Length > 0;
}
private IEnumerable SerializeModels(IEnumerable models)
{
var fieldsetJson = (from object model in models where null != model select SerializeModel(model)).ToList();
@@ -136,7 +155,9 @@ namespace Archetype.Umbraco.Serialization
if (value == null)
return null;
var jObj = IsExpandoObject(value) ? GetJObjectFromExpandoObject(value as IDictionary<string, object>) : GetJObject(value);
var jObj = IsExpandoObject(value)
? GetJObjectFromExpandoObject(value as IDictionary<string, object>)
: GetJObject(value);
var fieldsetJson = new StringBuilder();
var fieldsetWriter = new StringWriter(fieldsetJson);
@@ -232,7 +253,7 @@ namespace Archetype.Umbraco.Serialization
private string GetFieldsetName(Type type)
{
var attributes = type.GetCustomAttributes(true);
var archetypeDatatypeAttribute = (ArchetypeDatatypeAttribute)attributes.FirstOrDefault(attr => attr is ArchetypeDatatypeAttribute);
var archetypeDatatypeAttribute = (AsArchetypeAttribute)attributes.FirstOrDefault(attr => attr is AsArchetypeAttribute);
return archetypeDatatypeAttribute != null ? archetypeDatatypeAttribute.FieldsetName : type.Name;
}
@@ -245,7 +266,7 @@ namespace Archetype.Umbraco.Serialization
private bool IsValueArchetypeDatatype(Type type)
{
return type.GetCustomAttributes(typeof(ArchetypeDatatypeAttribute), true).Length > 0;
return type.GetCustomAttributes(typeof(AsArchetypeAttribute), true).Length > 0;
}
private JsonConverter GetArchetypeDatatypeConverter(object value)
@@ -2,11 +2,11 @@
namespace Archetype.Umbraco.Serialization
{
public class ArchetypeDatatypeAttribute : Attribute
public class AsArchetypeAttribute : Attribute
{
public string FieldsetName { get; set; }
public ArchetypeDatatypeAttribute(string fieldsetname)
public AsArchetypeAttribute(string fieldsetname)
{
FieldsetName = fieldsetname;
}
@@ -0,0 +1,8 @@
using System;
namespace Archetype.Umbraco.Serialization
{
public class AsFieldsetAttribute : Attribute
{
}
}