diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/JsonPatchTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/JsonPatchTest.cs index c9e3abd431..231cb6dfa4 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/JsonPatchTest.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/JsonPatchTest.cs @@ -11,6 +11,7 @@ using JsonPatchWebSite.Models; using Microsoft.AspNet.Builder; using Microsoft.Framework.DependencyInjection; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Xunit; namespace Microsoft.AspNet.Mvc.FunctionalTests @@ -303,5 +304,58 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests var body = await response.Content.ReadAsStringAsync(); Assert.Equal("{\"\":[\"The input was not valid.\"]}", body); } + + [Fact] + public async Task JsonPatch_JsonConverterOnProperty_Success() + { + // Arrange + var server = TestHelper.CreateServer(_app, SiteName, _configureServices); + var client = server.CreateClient(); + + var input = "[{ \"op\": \"add\", " + + "\"path\": \"Customer/Orders/2\", " + + "\"value\": { \"OrderType\": \"Type2\" }}]"; + var request = new HttpRequestMessage + { + Content = new StringContent(input, Encoding.UTF8, "application/json-patch+json"), + Method = new HttpMethod("PATCH"), + RequestUri = new Uri("http://localhost/jsonpatch/JsonPatchWithoutModelState") + }; + + // Act + var response = await client.SendAsync(request); + + // Assert + var body = await response.Content.ReadAsStringAsync(); + dynamic d = JObject.Parse(body); + Assert.Equal("OrderTypeSetInConverter", (string)d.Orders[2].OrderType); + } + + [Fact] + public async Task JsonPatch_JsonConverterOnClass_Success() + { + // Arrange + var server = TestHelper.CreateServer(_app, SiteName, _configureServices); + var client = server.CreateClient(); + + var input = "[{ \"op\": \"add\", " + + "\"path\": \"Product/ProductCategory\", " + + "\"value\": { \"CategoryName\": \"Name2\" }}]"; + var request = new HttpRequestMessage + { + Content = new StringContent(input, Encoding.UTF8, "application/json-patch+json"), + Method = new HttpMethod("PATCH"), + RequestUri = new Uri("http://localhost/jsonpatch/JsonPatchForProduct") + }; + + // Act + var response = await client.SendAsync(request); + + // Assert + var body = await response.Content.ReadAsStringAsync(); + dynamic d = JObject.Parse(body); + Assert.Equal("CategorySetInConverter", (string)d.ProductCategory.CategoryName); + + } } } \ No newline at end of file diff --git a/test/WebSites/JsonPatchWebSite/Controllers/JsonPatchController.cs b/test/WebSites/JsonPatchWebSite/Controllers/JsonPatchController.cs index 5e49b3fce0..c2cc1dab94 100644 --- a/test/WebSites/JsonPatchWebSite/Controllers/JsonPatchController.cs +++ b/test/WebSites/JsonPatchWebSite/Controllers/JsonPatchController.cs @@ -60,6 +60,16 @@ namespace JsonPatchWebSite.Controllers return new ObjectResult(customer); } + [HttpPatch] + public IActionResult JsonPatchForProduct([FromBody] JsonPatchDocument patchDoc) + { + var product = new Product(); + + patchDoc.ApplyTo(product); + + return new ObjectResult(product); + } + private Customer CreateCustomer() { return new Customer diff --git a/test/WebSites/JsonPatchWebSite/Models/Order.cs b/test/WebSites/JsonPatchWebSite/Models/Order.cs index 4517e216a2..57ca1cd6e3 100644 --- a/test/WebSites/JsonPatchWebSite/Models/Order.cs +++ b/test/WebSites/JsonPatchWebSite/Models/Order.cs @@ -1,10 +1,15 @@ // 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 Newtonsoft.Json; + namespace JsonPatchWebSite.Models { public class Order { public string OrderName { get; set; } + + [JsonConverter(typeof(ReplaceOrderTypeConverter))] + public string OrderType { get; set; } } } \ No newline at end of file diff --git a/test/WebSites/JsonPatchWebSite/Models/Product.cs b/test/WebSites/JsonPatchWebSite/Models/Product.cs new file mode 100644 index 0000000000..92bdd2e08c --- /dev/null +++ b/test/WebSites/JsonPatchWebSite/Models/Product.cs @@ -0,0 +1,20 @@ +// 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 Newtonsoft.Json; + +namespace JsonPatchWebSite.Models +{ + public class Product + { + public string ProductName { get; set; } + + public Category ProductCategory { get; set; } + } + + [JsonConverter(typeof(ProductCategoryConverter))] + public class Category + { + public string CategoryName { get; set; } + } +} diff --git a/test/WebSites/JsonPatchWebSite/ProductCategoryConverter.cs b/test/WebSites/JsonPatchWebSite/ProductCategoryConverter.cs new file mode 100644 index 0000000000..0e946c4245 --- /dev/null +++ b/test/WebSites/JsonPatchWebSite/ProductCategoryConverter.cs @@ -0,0 +1,50 @@ +// 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.Reflection; +using JsonPatchWebSite.Models; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace JsonPatchWebSite +{ + public class ProductCategoryConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return true; + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + // Load has to happen even if we are not using it. If removed, deserialization will throw an error - + //"Additional text found in JSON string after finishing deserializing object." + var obj = JObject.Load(reader); + + var category = new Category(); + category.CategoryName = "CategorySetInConverter"; + + return category; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var jo = new JObject(); + + foreach (var property in value.GetType().GetProperties()) + { + if (property.CanRead) + { + var propertyValue = property.GetValue(value); + if (propertyValue != null) + { + jo.Add(property.Name, JToken.FromObject(propertyValue, serializer)); + } + } + } + + jo.WriteTo(writer); + } + } +} diff --git a/test/WebSites/JsonPatchWebSite/ReplaceOrderTypeConverter.cs b/test/WebSites/JsonPatchWebSite/ReplaceOrderTypeConverter.cs new file mode 100644 index 0000000000..01dd1f09a1 --- /dev/null +++ b/test/WebSites/JsonPatchWebSite/ReplaceOrderTypeConverter.cs @@ -0,0 +1,29 @@ +// 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 Newtonsoft.Json; + +namespace JsonPatchWebSite +{ + public class ReplaceOrderTypeConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return true; + } + + public override object ReadJson( + JsonReader reader, + Type objectType, + object existingValue, JsonSerializer serializer) + { + return "OrderTypeSetInConverter"; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + serializer.Serialize(writer, value); + } + } +}