// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Buffers;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc.Formatters.Json.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool;
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Mvc.Formatters
{
///
/// A for JSON Patch (application/json-patch+json) content.
///
public class JsonPatchInputFormatter : JsonInputFormatter
{
///
/// Initializes a new instance.
///
/// The .
///
/// The . Should be either the application-wide settings
/// () or an instance
/// initially returned.
/// /// The .
/// The .
public JsonPatchInputFormatter(
ILogger logger,
JsonSerializerSettings serializerSettings,
ArrayPool charPool,
ObjectPoolProvider objectPoolProvider)
: base(logger, serializerSettings, charPool, objectPoolProvider)
{
// Clear all values and only include json-patch+json value.
SupportedMediaTypes.Clear();
SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationJsonPatch);
}
///
public async override Task ReadRequestBodyAsync(
InputFormatterContext context,
Encoding encoding)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (encoding == null)
{
throw new ArgumentNullException(nameof(encoding));
}
var result = await base.ReadRequestBodyAsync(context, encoding);
if (!result.HasError)
{
var jsonPatchDocument = (IJsonPatchDocument)result.Model;
if (jsonPatchDocument != null && SerializerSettings.ContractResolver != null)
{
jsonPatchDocument.ContractResolver = SerializerSettings.ContractResolver;
}
}
return result;
}
///
public override bool CanRead(InputFormatterContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var modelTypeInfo = context.ModelType.GetTypeInfo();
if (!typeof(IJsonPatchDocument).GetTypeInfo().IsAssignableFrom(modelTypeInfo) ||
!modelTypeInfo.IsGenericType)
{
return false;
}
return base.CanRead(context);
}
}
}