diff --git a/WebApi.Hal.Web/Api/BeerDetailController.cs b/WebApi.Hal.Web/Api/BeerDetailController.cs index c268547..908ccf1 100644 --- a/WebApi.Hal.Web/Api/BeerDetailController.cs +++ b/WebApi.Hal.Web/Api/BeerDetailController.cs @@ -1,5 +1,7 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using WebApi.Hal.Web.Api.Resources; @@ -64,5 +66,45 @@ public void Put(int id, BeerDetailRepresentation beer) // we should get the links and all the embedded objects deserialized // we'd be better off creating a client to test the full deserializing, but this way is cheap for now } + + [HttpGet("largeset")] + public async Task GetLargeSet(int setSize = 500) + { + var random = new Random(); + var largeSet = new BeerDetailRepresentation[setSize]; + Parallel.For(0, setSize, index => + { + largeSet[index] = new BeerDetailRepresentation + { + Id = index + 1, + Name = $"Test beer name {Guid.NewGuid()}", + Reviews = new List(), + Style = new BeerStyleRepresentation + { + Id = random.Next(1, 50), + Name = $"Test beer style name {Guid.NewGuid()}" + }, + Brewery = new BreweryRepresentation + { + Id = random.Next(1, 10), + Name = $"Test brewery name {Guid.NewGuid()}" + } + }; + var numberOfReviews = random.Next(2, 20); + for (var reviewIndex = 0; reviewIndex < numberOfReviews; reviewIndex++) + { + largeSet[index].Reviews.Add(new ReviewRepresentation + { + Id = random.Next(setSize * 10, setSize * 100) + largeSet[index].Id, + Content = $"Test beer review content {Guid.NewGuid()}", + Title = $"Test beer review title {Guid.NewGuid()}", + Beer_Id = largeSet[index].Id + }); + } + }); + + await Task.CompletedTask; + return new BeerDetailListRepresentation(largeSet, largeSet.Length, 1, 1, LinkTemplates.BeerDetails.GetBeerDetail); + } } } \ No newline at end of file diff --git a/WebApi.Hal.Web/Api/Resources/BeerDetailListRepresentation.cs b/WebApi.Hal.Web/Api/Resources/BeerDetailListRepresentation.cs new file mode 100644 index 0000000..a32a6f5 --- /dev/null +++ b/WebApi.Hal.Web/Api/Resources/BeerDetailListRepresentation.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace WebApi.Hal.Web.Api.Resources +{ + public class BeerDetailListRepresentation : PagedRepresentationList + { + public BeerDetailListRepresentation(IList beerDetailList, int totalResults, int totalPages, int page, Link uriTemplate) : + base(beerDetailList, totalResults, totalPages, page, uriTemplate, null) + { + } + } +} \ No newline at end of file diff --git a/WebApi.Hal/JsonConverters/ResourceConverter.cs b/WebApi.Hal/JsonConverters/ResourceConverter.cs index 36c62f8..a11ddaa 100644 --- a/WebApi.Hal/JsonConverters/ResourceConverter.cs +++ b/WebApi.Hal/JsonConverters/ResourceConverter.cs @@ -17,12 +17,8 @@ public ResourceConverter() public ResourceConverter(IHypermediaResolver hypermediaConfiguration) { - if (hypermediaConfiguration == null) - { - throw new ArgumentNullException(nameof(hypermediaConfiguration)); - } - - HypermediaResolver = hypermediaConfiguration; + HypermediaResolver = hypermediaConfiguration ?? + throw new ArgumentNullException(nameof(hypermediaConfiguration)); } public IHypermediaResolver HypermediaResolver { get; } @@ -44,12 +40,42 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s if (linksBackup.Count == 0) resource.Links = null; // avoid serialization - var saveContext = serializer.Context; + var localJsonSerializer = JsonSerializer.Create(); + localJsonSerializer.CheckAdditionalContent = serializer.CheckAdditionalContent; + localJsonSerializer.Context = serializer.Context; + localJsonSerializer.ContractResolver = serializer.ContractResolver; + localJsonSerializer.ConstructorHandling = serializer.ConstructorHandling; + foreach (var converter in serializer.Converters.Where(converter => converter != this)) + { + localJsonSerializer.Converters.Add(converter); + } + + localJsonSerializer.Culture = serializer.Culture; + localJsonSerializer.DateFormatHandling = serializer.DateFormatHandling; + localJsonSerializer.DateFormatString = serializer.DateFormatString; + localJsonSerializer.DateParseHandling = serializer.DateParseHandling; + localJsonSerializer.DateTimeZoneHandling = serializer.DateTimeZoneHandling; + localJsonSerializer.DefaultValueHandling = serializer.DefaultValueHandling; + localJsonSerializer.EqualityComparer = serializer.EqualityComparer; + localJsonSerializer.FloatFormatHandling = serializer.FloatFormatHandling; + localJsonSerializer.FloatParseHandling = serializer.FloatParseHandling; + localJsonSerializer.Formatting = serializer.Formatting; + localJsonSerializer.MaxDepth = serializer.MaxDepth; + localJsonSerializer.MetadataPropertyHandling = serializer.MetadataPropertyHandling; + localJsonSerializer.MissingMemberHandling = serializer.MissingMemberHandling; + localJsonSerializer.NullValueHandling = serializer.NullValueHandling; + localJsonSerializer.ObjectCreationHandling = serializer.ObjectCreationHandling; + localJsonSerializer.PreserveReferencesHandling = serializer.PreserveReferencesHandling; + localJsonSerializer.ReferenceLoopHandling = serializer.ReferenceLoopHandling; + localJsonSerializer.ReferenceResolver = serializer.ReferenceResolver; + localJsonSerializer.SerializationBinder = serializer.SerializationBinder; + localJsonSerializer.StringEscapeHandling = serializer.StringEscapeHandling; + localJsonSerializer.TraceWriter = serializer.TraceWriter; + localJsonSerializer.TypeNameAssemblyFormatHandling = serializer.TypeNameAssemblyFormatHandling; + localJsonSerializer.TypeNameHandling = serializer.TypeNameHandling; + resource.ConverterContext = GetResourceConverterContext(); - serializer.Converters.Remove(this); - serializer.Serialize(writer, resource); - serializer.Converters.Add(this); - serializer.Context = saveContext; + localJsonSerializer.Serialize(writer, resource); if (linksBackup.Count == 0) resource.Links = linksBackup;