// 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 . [Obsolete("This constructor is obsolete and will be removed in a future version.")] public JsonPatchInputFormatter( ILogger logger, JsonSerializerSettings serializerSettings, ArrayPool charPool, ObjectPoolProvider objectPoolProvider) : this(logger, serializerSettings, charPool, objectPoolProvider, suppressInputFormatterBuffering: false) { } /// /// Initializes a new instance. /// /// The . /// /// The . Should be either the application-wide settings /// () or an instance /// initially returned. /// /// The . /// The . /// Flag to buffer entire request body before deserializing it. [Obsolete("This constructor is obsolete and will be removed in a future version.")] public JsonPatchInputFormatter( ILogger logger, JsonSerializerSettings serializerSettings, ArrayPool charPool, ObjectPoolProvider objectPoolProvider, bool suppressInputFormatterBuffering) : this(logger, serializerSettings, charPool, objectPoolProvider, suppressInputFormatterBuffering, suppressJsonDeserializationExceptionMessages: false) { } /// /// Initializes a new instance. /// /// The . /// /// The . Should be either the application-wide settings /// () or an instance /// initially returned. /// /// The . /// The . /// Flag to buffer entire request body before deserializing it. /// If , JSON deserialization exception messages will replaced by a generic message in model state. [Obsolete("This constructor is obsolete and will be removed in a future version.")] public JsonPatchInputFormatter( ILogger logger, JsonSerializerSettings serializerSettings, ArrayPool charPool, ObjectPoolProvider objectPoolProvider, bool suppressInputFormatterBuffering, bool suppressJsonDeserializationExceptionMessages) : base(logger, serializerSettings, charPool, objectPoolProvider, suppressInputFormatterBuffering, suppressJsonDeserializationExceptionMessages) { // Clear all values and only include json-patch+json value. SupportedMediaTypes.Clear(); SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationJsonPatch); } /// /// Initializes a new instance. /// /// The . /// /// The . Should be either the application-wide settings /// () or an instance /// initially returned. /// /// The . /// The . /// The . public JsonPatchInputFormatter( ILogger logger, JsonSerializerSettings serializerSettings, ArrayPool charPool, ObjectPoolProvider objectPoolProvider, MvcOptions options) : base(logger, serializerSettings, charPool, objectPoolProvider, options) { // Clear all values and only include json-patch+json value. SupportedMediaTypes.Clear(); SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationJsonPatch); } /// public override InputFormatterExceptionPolicy ExceptionPolicy { get { if (GetType() == typeof(JsonPatchInputFormatter)) { return InputFormatterExceptionPolicy.MalformedInputExceptions; } return InputFormatterExceptionPolicy.AllExceptions; } } /// 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); } } }