using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
using System;
using System.Threading.Tasks;
using Timeline.Models;
namespace Timeline.Formatters
{
///
/// Formatter that reads body as bytes.
///
public class BytesInputFormatter : InputFormatter
{
///
///
///
public BytesInputFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/png"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/jpeg"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/gif"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/webp"));
}
///
public override bool CanRead(InputFormatterContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (context.ModelType == typeof(ByteData))
return true;
return false;
}
///
public override async Task ReadRequestBodyAsync(InputFormatterContext context)
{
var request = context.HttpContext.Request;
var contentLength = request.ContentLength;
var logger = context.HttpContext.RequestServices.GetRequiredService>();
if (contentLength == null)
{
logger.LogInformation("Failed to read body as bytes. Content-Length is not set.");
return await InputFormatterResult.FailureAsync();
}
if (contentLength == 0)
{
logger.LogInformation("Failed to read body as bytes. Content-Length is 0.");
return await InputFormatterResult.FailureAsync();
}
var bodyStream = request.Body;
var data = new byte[contentLength.Value];
var bytesRead = await bodyStream.ReadAsync(data);
if (bytesRead != contentLength)
{
logger.LogInformation("Failed to read body as bytes. Actual length of body is smaller than Content-Length.");
return await InputFormatterResult.FailureAsync();
}
var extraByte = new byte[1];
if (await bodyStream.ReadAsync(extraByte) != 0)
{
logger.LogInformation("Failed to read body as bytes. Actual length of body is greater than Content-Length.");
return await InputFormatterResult.FailureAsync();
}
return await InputFormatterResult.SuccessAsync(new ByteData(data, request.ContentType));
}
}
}