зеркало из https://github.com/Azure/Sia-Gateway.git
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:
Родитель
01d95fe564
Коммит
40deed01ae
|
@ -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);
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче