Skip to content

Commit

Permalink
Fix for ResourceConverter class. Now when multiple asynchronous reque…
Browse files Browse the repository at this point in the history
…sts are executed concurrently the correct responses are returned.
  • Loading branch information
cosmin-ciuc committed Sep 22, 2018
1 parent ec45be6 commit 595195a
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 12 deletions.
44 changes: 43 additions & 1 deletion 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;
Expand Down Expand Up @@ -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<BeerDetailListRepresentation> 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<ReviewRepresentation>(),
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);
}
}
}
12 changes: 12 additions & 0 deletions 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<BeerDetailRepresentation>
{
public BeerDetailListRepresentation(IList<BeerDetailRepresentation> beerDetailList, int totalResults, int totalPages, int page, Link uriTemplate) :
base(beerDetailList, totalResults, totalPages, page, uriTemplate, null)
{
}
}
}
48 changes: 37 additions & 11 deletions WebApi.Hal/JsonConverters/ResourceConverter.cs
Expand Up @@ -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; }
Expand All @@ -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;
Expand Down

0 comments on commit 595195a

Please sign in to comment.