Permalink
Browse files

Generate simpler json output

  • Loading branch information...
ayende committed Sep 26, 2011
1 parent f85efe7 commit 5fd12c6228ac2ef3afd9e6b4393924bd57aec32d
@@ -11,6 +11,7 @@
using System.Runtime.CompilerServices;
using System.Transactions;
#endif
+using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Raven.Abstractions.Commands;
using Raven.Abstractions.Data;
@@ -922,13 +923,78 @@ private RavenJObject GetObjectAsJson(object entity)
if (cachedJsonDocs != null && cachedJsonDocs.TryGetValue(entity, out jObject))
return jObject;
-
- jObject = RavenJObject.FromObject(entity, Conventions.CreateSerializer());
+
+ var jsonSerializer = Conventions.CreateSerializer();
+ jObject = RavenJObject.FromObject(entity, jsonSerializer);
+
+ if (jsonSerializer.TypeNameHandling == TypeNameHandling.Auto)// remove the default types
+ TrySimplfyingJson(jObject);
+
if (cachedJsonDocs != null)
cachedJsonDocs[entity] = jObject;
return jObject;
}
+ private static void TrySimplfyingJson(RavenJObject jObject)
+ {
+ var deferredActions = new List<Action>();
+ foreach (var kvp in jObject)
+ {
+ var prop = kvp;
+ if(prop.Value == null)
+ continue;
+ var obj = prop.Value as RavenJObject;
+ if(obj == null)
+ continue;
+ if (ShouldSimplfyJsonBasedOnType(obj.Value<string>("$type")) == false)
+ continue;
+
+ if (obj.ContainsKey("$values") == false)
+ {
+ deferredActions.Add(() => obj.Remove("$type"));
+ }
+ else
+ {
+ deferredActions.Add(() => jObject[prop.Key] = obj["$values"]);
+ }
+ }
+ foreach (var deferredAction in deferredActions)
+ {
+ deferredAction();
+ }
+
+ foreach (var prop in jObject.Where(prop => prop.Value != null))
+ {
+ switch (prop.Value.Type)
+ {
+ case JTokenType.Array:
+ foreach (var item in ((RavenJArray)prop.Value))
+ {
+ var ravenJObject = item as RavenJObject;
+ if (ravenJObject != null)
+ TrySimplfyingJson(ravenJObject);
+ }
+ break;
+ case JTokenType.Object:
+ TrySimplfyingJson((RavenJObject)prop.Value);
+ break;
+ }
+ }
+ }
+
+ private static bool ShouldSimplfyJsonBasedOnType(string typeValue)
+ {
+ if (typeValue == null)
+ return false;
+ if (typeValue.StartsWith("System.Collections.Generic.List`1[["))
+ return true;
+ if (typeValue.StartsWith("System.Collections.Generic.Dictionary`2[["))
+ return true;
+ if (typeValue.EndsWith("[], mscorlib")) // array
+ return true;
+ return false;
+ }
+
/// <summary>
/// All calls to convert an entity to a json object would be cache
@@ -0,0 +1,76 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Xunit;
+using System.Linq;
+
+namespace Raven.Tests.Bugs
+{
+ public class SimpleJson : RavenTest
+ {
+ [Fact]
+ public void ShouldNotGenerateComplexJsonForDefaultValues_Array()
+ {
+ using(var store = NewDocumentStore())
+ {
+ using(var session = store.OpenSession())
+ {
+ session.Store(new TestItem
+ {
+ Tags = new[]{"item", "two", "four"}
+ });
+ session.SaveChanges();
+ }
+
+ var doc = store.DatabaseCommands.Get("testitems/1").DataAsJson.ToString(Formatting.None);
+ Assert.Equal("{\"Tags\":[\"item\",\"two\",\"four\"],\"Attributes\":null}", doc);
+ }
+ }
+
+ [Fact]
+ public void ShouldNotGenerateComplexJsonForDefaultValues_List()
+ {
+ using (var store = NewDocumentStore())
+ {
+ using (var session = store.OpenSession())
+ {
+ session.Store(new TestItem
+ {
+ Tags = new[] { "item", "two", "four" }.ToList()
+ });
+ session.SaveChanges();
+ }
+
+ var doc = store.DatabaseCommands.Get("testitems/1").DataAsJson.ToString(Formatting.None);
+ Assert.Equal("{\"Tags\":[\"item\",\"two\",\"four\"],\"Attributes\":null}", doc);
+ }
+ }
+
+ [Fact]
+ public void ShouldNotGenerateComplexJsonForDefaultValues_Dictionary()
+ {
+ using (var store = NewDocumentStore())
+ {
+ using (var session = store.OpenSession())
+ {
+ session.Store(new TestItem
+ {
+ Attributes = new Dictionary<string, string>
+ {
+ {"User","Ayende"}
+ }
+ });
+ session.SaveChanges();
+ }
+
+ var doc = store.DatabaseCommands.Get("testitems/1").DataAsJson.ToString(Formatting.None);
+ Assert.Equal("{\"Tags\":null,\"Attributes\":{\"User\":\"Ayende\"}}", doc);
+ }
+ }
+
+ public class TestItem
+ {
+ public ICollection<string> Tags { get; set; }
+ public IDictionary<string, string> Attributes { get; set; }
+ }
+ }
+}
@@ -422,6 +422,7 @@
<Compile Include="Bugs\SelectManyTests .cs" />
<Compile Include="Bugs\SerializingDates.cs" />
<Compile Include="Bugs\SerializingEntities.cs" />
+ <Compile Include="Bugs\SimpleJson.cs" />
<Compile Include="Bugs\SinglePropertyDocument.cs" />
<Compile Include="Bugs\MapRedue\VersionedDocument.cs" />
<Compile Include="Bugs\spokeypokey.cs" />
View
@@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raven.Web", "Raven.Web\Rave
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raven.Munin.Tests", "Modules\Munin\Raven.Munin.Tests\Raven.Munin.Tests.csproj", "{08BE1CAB-13B1-4707-A0A3-6A2FDC1F916D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raven.Studio", "Raven.Studio\Raven.Studio.csproj", "{AB130CB7-E4D4-4496-BEE6-0538963475FC}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -191,6 +193,16 @@ Global
{08BE1CAB-13B1-4707-A0A3-6A2FDC1F916D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{08BE1CAB-13B1-4707-A0A3-6A2FDC1F916D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{08BE1CAB-13B1-4707-A0A3-6A2FDC1F916D}.Release|x86.ActiveCfg = Release|Any CPU
+ {AB130CB7-E4D4-4496-BEE6-0538963475FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB130CB7-E4D4-4496-BEE6-0538963475FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB130CB7-E4D4-4496-BEE6-0538963475FC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {AB130CB7-E4D4-4496-BEE6-0538963475FC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {AB130CB7-E4D4-4496-BEE6-0538963475FC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AB130CB7-E4D4-4496-BEE6-0538963475FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AB130CB7-E4D4-4496-BEE6-0538963475FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB130CB7-E4D4-4496-BEE6-0538963475FC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {AB130CB7-E4D4-4496-BEE6-0538963475FC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {AB130CB7-E4D4-4496-BEE6-0538963475FC}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

0 comments on commit 5fd12c6

Please sign in to comment.