-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Make SystemTextJsonInputFormatter IAsyncEnumerable aware #43489
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Triage: this work would depend on adding support for Stream parameters in MVC actions, see #41540. |
@captainsafia im sure there’s aspects I’m not considering, but we did get this working inserting a new InputFormatter into the pipeline. Would it be helpful to post the approach here? |
I would like to see your approach, as currently I'm doing that by reading the Body in the action method and would like to have an argument in the method instead... |
I am on vacation now away from my computer, back on April 6th. Can post example then! |
@CheloXL As promised (a day late :) ) using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Net.Http.Headers;
using System.Text;
using System.Text.Json;
namespace Example;
internal class AsyncEnumerableJsonInputFormatter : TextInputFormatter, IInputFormatterExceptionPolicy
{
private static readonly Type _asyncEnumerableType = typeof(IAsyncEnumerable<>);
public InputFormatterExceptionPolicy ExceptionPolicy => InputFormatterExceptionPolicy.MalformedInputExceptions;
public JsonSerializerOptions SerializerOptions { get; }
public AsyncEnumerableJsonInputFormatter()
{
SerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);
SupportedEncodings.Add(UTF8EncodingWithoutBOM);
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}
protected override bool CanReadType(Type type)
{
return type.IsGenericType && type.GetGenericTypeDefinition() == _asyncEnumerableType;
}
public override Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{
var modelReaderType = typeof(AsyncEnumerableStreamReader<>).MakeGenericType(context.ModelType.GetGenericArguments()[0]);
var modelReader = (IAsyncEnumerableStreamReader)Activator.CreateInstance(modelReaderType)!;
var result = InputFormatterResult.Success(modelReader.ReadModel(context.HttpContext.Request.Body, SerializerOptions));
return Task.FromResult(result);
}
private interface IAsyncEnumerableStreamReader
{
object ReadModel(Stream inputStream, JsonSerializerOptions serializerOptions);
}
private class AsyncEnumerableStreamReader<T> : IAsyncEnumerableStreamReader
{
public object ReadModel(Stream inputStream, JsonSerializerOptions serializerOptions)
{
return JsonSerializer.DeserializeAsyncEnumerable<T>(inputStream, serializerOptions);
}
}
} Bind to your MvcOptions during AddMvc (or calling builder.Services.AddMvc(options =>
{
options.InputFormatters.Insert(0, new AsyncEnumerableJsonInputFormatter())
}); Controller methods now can accept |
Excellent, thank you very much! |
In ASP.NET Core 6, preventing buffering of output results was completed
Can we achieve the same benefit on the Input / Request side as well via the SystemTextJsonInputFormatter?
The text was updated successfully, but these errors were encountered: