Added dynamic output formatter, which deserializes dynamic data when that data can't be deserialized as part of an Automapper Map operation (such as collections converted using AutoMapper ProjectTo)

This commit is contained in:
Philip Dimitratos 2017-10-16 17:18:46 -07:00
Родитель 01d95fe564
Коммит 40deed01ae
3 изменённых файлов: 61 добавлений и 3 удалений

Просмотреть файл

@ -15,7 +15,5 @@ namespace Sia.Domain
public DateTime Occurred { get; set; }
public DateTime EventFired { get; set; }
public dynamic Data { get; set; } = new ExpandoObject();
}
}

Просмотреть файл

@ -22,6 +22,8 @@ using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Runtime.Loader;
using Sia.Gateway.Protocol;
using System.Buffers;
namespace Sia.Gateway.Initialization
{
@ -129,7 +131,12 @@ namespace Sia.Gateway.Initialization
=> new UrlHelper(iFactory.GetService<IActionContextAccessor>().ActionContext)
);
services.AddMvc();
services.AddMvc(options =>
{
options.OutputFormatters.Insert(0, new DynamicOutputFormatter(
new MvcJsonOptions().SerializerSettings,
ArrayPool<char>.Shared));
});
services
.AddAuthentication(authOptions =>
{

Просмотреть файл

@ -0,0 +1,53 @@
using Microsoft.AspNetCore.Mvc.Formatters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Buffers;
using System.Text;
using Sia.Shared.Data;
namespace Sia.Gateway.Protocol
{
public class DynamicOutputFormatter : JsonOutputFormatter
{
public DynamicOutputFormatter(JsonSerializerSettings serializerSettings, ArrayPool<char> charPool)
: base(serializerSettings, charPool)
{
}
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
var dataStream = (IEnumerable<IDynamicDataSource>)context.Object;
foreach (var objectToWrite in dataStream)
{
var dynamicData = objectToWrite.Data;
if (dynamicData is string) objectToWrite.Data = Deserialize((string)dynamicData);
}
return base.WriteResponseBodyAsync(context, selectedEncoding);
}
private const int NumberOfCharactersInGenericTypeNotUsedByGetInterfaceMethod = 3;
protected override bool CanWriteType(Type type)
{
if (!type.IsGenericType) return false;
if (type.GetGenericArguments().Count() != 1) return false;
var enumIntName = typeof(IEnumerable<>).ToString();
var enumerableInterface = type.GetInterface(enumIntName
.Substring(0, enumIntName.Length - NumberOfCharactersInGenericTypeNotUsedByGetInterfaceMethod));
if (enumerableInterface is null) return false;
var canWrite = !(type.GetGenericArguments()[0].GetInterface(nameof(IDynamicDataSource)) is null);
return canWrite;
}
private object Deserialize(string serializedData) => JsonConvert.DeserializeObject(serializedData);
}
}