From e297c54af13756aed72d90fafdb4eb4f9519fb04 Mon Sep 17 00:00:00 2001 From: Rex Ng Date: Sun, 20 Oct 2019 10:13:03 +0800 Subject: [PATCH 1/5] Clean up input and output formatters --- .../Formatter.cs | 105 +++++++++--------- 1 file changed, 51 insertions(+), 54 deletions(-) diff --git a/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs b/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs index a7a0fec..cea9158 100644 --- a/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs +++ b/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs @@ -3,82 +3,79 @@ namespace Utf8Json.AspNetCoreMvcFormatter { - public class JsonOutputFormatter : IOutputFormatter //, IApiResponseTypeMetadataProvider + public class Utf8JsonOutputFormatter : IOutputFormatter { - const string ContentType = "application/json"; - static readonly string[] SupportedContentTypes = new[] { ContentType }; + private const string ContentType = "application/json"; + private readonly IJsonFormatterResolver _jsonFormatterResolver; - readonly IJsonFormatterResolver resolver; - - public JsonOutputFormatter() - : this(null) - { - - } - public JsonOutputFormatter(IJsonFormatterResolver resolver) + public Utf8JsonOutputFormatter() : this(null) { - this.resolver = resolver ?? JsonSerializer.DefaultResolver; } - //public IReadOnlyList GetSupportedContentTypes(string contentType, Type objectType) - //{ - // return SupportedContentTypes; - //} + public Utf8JsonOutputFormatter( + IJsonFormatterResolver jsonFormatterResolver) + => _jsonFormatterResolver = + jsonFormatterResolver ?? JsonSerializer.DefaultResolver; public bool CanWriteResult(OutputFormatterCanWriteContext context) - { - return true; - } + => context.HttpContext.Request.Headers.TryGetValue( + "Accept", + out var acceptValues) && + acceptValues.All(accept => accept.Contains( + ContentType)); public Task WriteAsync(OutputFormatterWriteContext context) { - context.HttpContext.Response.ContentType = ContentType; - - // when 'object' use the concrete type(object.GetType()) - if (context.ObjectType == typeof(object)) - { - return JsonSerializer.NonGeneric.SerializeAsync(context.HttpContext.Response.Body, context.Object, resolver); - } - else - { - return JsonSerializer.NonGeneric.SerializeAsync(context.ObjectType, context.HttpContext.Response.Body, context.Object, resolver); - } + var objectType = context.ObjectType; + var obj = context.Object; + + var serializeType = objectType == typeof(object) + ? obj.GetType() + : objectType; + + return JsonSerializer.NonGeneric.SerializeAsync( + serializeType, + context.HttpContext.Response.Body, + obj, + _jsonFormatterResolver); } } - public class JsonInputFormatter : IInputFormatter // , IApiRequestFormatMetadataProvider + public class Utf8JsonInputFormatter : IInputFormatter { - const string ContentType = "application/json"; - static readonly string[] SupportedContentTypes = new[] { ContentType }; + private const string ContentType = "application/json"; + private readonly IJsonFormatterResolver _jsonFormatterResolver; - readonly IJsonFormatterResolver resolver; - - public JsonInputFormatter() - : this(null) - { - - } - - public JsonInputFormatter(IJsonFormatterResolver resolver) + public Utf8JsonInputFormatter() : this(null) { - this.resolver = resolver ?? JsonSerializer.DefaultResolver; } - //public IReadOnlyList GetSupportedContentTypes(string contentType, Type objectType) - //{ - // return SupportedContentTypes; - //} + public Utf8JsonInputFormatter( + IJsonFormatterResolver jsonFormatterResolver) + => _jsonFormatterResolver = + jsonFormatterResolver ?? JsonSerializer.DefaultResolver; public bool CanRead(InputFormatterContext context) - { - return true; - } + => context.HttpContext.Request.ContentType == + ContentType; - public Task ReadAsync(InputFormatterContext context) + public async Task ReadAsync( + InputFormatterContext context) { - var request = context.HttpContext.Request; - var result = JsonSerializer.NonGeneric.Deserialize(context.ModelType, request.Body, resolver); - return InputFormatterResult.SuccessAsync(result); + try + { + var model = await JsonSerializer.NonGeneric + .DeserializeAsync( + context.ModelType, + context.HttpContext.Request.Body, + _jsonFormatterResolver) + .ConfigureAwait(false); + return InputFormatterResult.Success(model); + } + catch (JsonParsingException) + { + return InputFormatterResult.Failure(); + } } } } \ No newline at end of file From 4c4e795b062cc291be3da639db600fb314a0e048 Mon Sep 17 00:00:00 2001 From: Rex Ng Date: Sun, 20 Oct 2019 10:24:04 +0800 Subject: [PATCH 2/5] Set response content type to application/json --- src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs b/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs index cea9158..7916c60 100644 --- a/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs +++ b/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs @@ -26,6 +26,8 @@ public bool CanWriteResult(OutputFormatterCanWriteContext context) public Task WriteAsync(OutputFormatterWriteContext context) { + context.HttpContext.Response.ContentType = ContentType; + var objectType = context.ObjectType; var obj = context.Object; From 473d0d5205efeb7f7b51ea900b84a1c62180311f Mon Sep 17 00:00:00 2001 From: Rex Ng Date: Mon, 21 Oct 2019 09:14:08 +0800 Subject: [PATCH 3/5] Fix compile error --- src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs b/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs index 7916c60..d3ce9d8 100644 --- a/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs +++ b/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Mvc.Formatters; +using System.Linq; +using Microsoft.AspNetCore.Mvc.Formatters; using System.Threading.Tasks; namespace Utf8Json.AspNetCoreMvcFormatter @@ -80,4 +81,4 @@ public async Task ReadAsync( } } } -} \ No newline at end of file +} From d4311e811427196bdabb38d275e4a11255a9ef94 Mon Sep 17 00:00:00 2001 From: Rex Ng Date: Mon, 21 Oct 2019 09:14:48 +0800 Subject: [PATCH 4/5] Extract variable --- src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs b/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs index d3ce9d8..40c62e4 100644 --- a/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs +++ b/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs @@ -27,8 +27,9 @@ public bool CanWriteResult(OutputFormatterCanWriteContext context) public Task WriteAsync(OutputFormatterWriteContext context) { - context.HttpContext.Response.ContentType = ContentType; - + var response = context.HttpContext.Response; + response.ContentType = ContentType; + var objectType = context.ObjectType; var obj = context.Object; @@ -38,7 +39,7 @@ public Task WriteAsync(OutputFormatterWriteContext context) return JsonSerializer.NonGeneric.SerializeAsync( serializeType, - context.HttpContext.Response.Body, + response.Body, obj, _jsonFormatterResolver); } From f59e72c047c7c83bb7a9c3475bc8118e081f51b5 Mon Sep 17 00:00:00 2001 From: Rex Ng Date: Mon, 21 Oct 2019 09:16:38 +0800 Subject: [PATCH 5/5] Return no value when stream length is zero --- src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs b/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs index 40c62e4..d486ceb 100644 --- a/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs +++ b/src/Utf8Json.AspNetCoreMvcFormatter/Formatter.cs @@ -66,12 +66,18 @@ public bool CanRead(InputFormatterContext context) public async Task ReadAsync( InputFormatterContext context) { + var body = context.HttpContext.Request.Body; + if (body.CanSeek && body.Length == 0) + { + return InputFormatterResult.NoValue(); + } + try { var model = await JsonSerializer.NonGeneric .DeserializeAsync( context.ModelType, - context.HttpContext.Request.Body, + body, _jsonFormatterResolver) .ConfigureAwait(false); return InputFormatterResult.Success(model);