Serialize JSON using camel case by default
- #4283 - update `JsonSerializerSettingsProvider` to choose the `CamelCaseNamingStrategy`
This commit is contained in:
parent
31ec88526a
commit
62803d5979
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Formatters
|
||||
{
|
||||
|
|
@ -20,6 +21,11 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
{
|
||||
return new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy(),
|
||||
},
|
||||
|
||||
MissingMemberHandling = MissingMemberHandling.Ignore,
|
||||
|
||||
// Limit the object graph we'll consume to a fixed depth. This prevents stackoverflow exceptions
|
||||
|
|
@ -28,7 +34,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
|
||||
// Do not change this setting
|
||||
// Setting this to None prevents Json.NET from loading malicious, unsafe, or security-sensitive types
|
||||
TypeNameHandling = TypeNameHandling.None
|
||||
TypeNameHandling = TypeNameHandling.None,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using System.Net.Http;
|
|||
using System.Net.Http.Headers;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Xunit;
|
||||
|
|
@ -217,15 +218,10 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task JsonHelper_RendersJson()
|
||||
public async Task JsonHelper_RendersJson_WithCamelCaseNames()
|
||||
{
|
||||
// Arrange
|
||||
var json = JsonConvert.SerializeObject(new BasicWebSite.Models.Person()
|
||||
{
|
||||
Id = 9000,
|
||||
Name = "John <b>Smith</b>"
|
||||
});
|
||||
|
||||
var json = "{\"id\":9000,\"fullName\":\"John <b>Smith</b>\"}";
|
||||
var expectedBody = string.Format(
|
||||
@"<script type=""text/javascript"">
|
||||
var json = {0};
|
||||
|
|
@ -244,17 +240,10 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task JsonHelperWithSettings_RendersJson()
|
||||
public async Task JsonHelperWithSettings_RendersJson_WithNamesUnchanged()
|
||||
{
|
||||
// Arrange
|
||||
var json = JsonConvert.SerializeObject(
|
||||
new BasicWebSite.Models.Person()
|
||||
{
|
||||
Id = 9000,
|
||||
Name = "John <b>Smith</b>"
|
||||
},
|
||||
new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
|
||||
|
||||
var json = "{\"id\":9000,\"FullName\":\"John <b>Smith</b>\"}";
|
||||
var expectedBody = string.Format(
|
||||
@"<script type=""text/javascript"">
|
||||
var json = {0};
|
||||
|
|
@ -262,7 +251,29 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
json);
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync("Home/JsonHelperWithSettingsInView");
|
||||
var response = await Client.GetAsync("Home/JsonHelperWithSettingsInView?snakeCase=false");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("text/html", response.Content.Headers.ContentType.MediaType);
|
||||
|
||||
var actualBody = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedBody, actualBody, ignoreLineEndingDifferences: true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task JsonHelperWithSettings_RendersJson_WithSnakeCaseNames()
|
||||
{
|
||||
// Arrange
|
||||
var json = "{\"id\":9000,\"full_name\":\"John <b>Smith</b>\"}";
|
||||
var expectedBody = string.Format(
|
||||
@"<script type=""text/javascript"">
|
||||
var json = {0};
|
||||
</script>",
|
||||
json);
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync("Home/JsonHelperWithSettingsInView?snakeCase=true");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
{
|
||||
// Arrange
|
||||
var expectedContentType = MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
|
||||
var expectedBody = $"{{{Environment.NewLine} \"Name\": \"My name\",{Environment.NewLine}" +
|
||||
$" \"Address\": \"My address\"{Environment.NewLine}}}";
|
||||
var expectedBody = $"{{{Environment.NewLine} \"name\": \"My name\",{Environment.NewLine}" +
|
||||
$" \"address\": \"My address\"{Environment.NewLine}}}";
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync("http://localhost/Normal/MultipleAllowedContentTypes");
|
||||
|
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
{
|
||||
// Arrange
|
||||
var expectedContentType = MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
|
||||
var expectedOutput = "{\"Name\":\"John\",\"Address\":\"One Microsoft Way\"}";
|
||||
var expectedOutput = "{\"name\":\"John\",\"address\":\"One Microsoft Way\"}";
|
||||
var request = new HttpRequestMessage(
|
||||
HttpMethod.Get,
|
||||
"http://localhost/ContentNegotiation/UserInfo_ProducesWithTypeOnly");
|
||||
|
|
@ -287,7 +287,7 @@ END:VCARD
|
|||
{
|
||||
// Arrange
|
||||
var expectedContentType = MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
|
||||
var expectedBody = "{\"MethodName\":\"Produces_WithNonObjectResult\"}";
|
||||
var expectedBody = "{\"methodName\":\"Produces_WithNonObjectResult\"}";
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync("http://localhost/ProducesJson/Produces_WithNonObjectResult");
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.Net.Http;
|
|||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
|
@ -35,7 +36,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
Name = "John Williams"
|
||||
};
|
||||
|
||||
var serializerSettings = new JsonSerializerSettings();
|
||||
var serializerSettings = JsonSerializerSettingsProvider.CreateSerializerSettings();
|
||||
serializerSettings.Formatting = Formatting.Indented;
|
||||
var expectedBody = JsonConvert.SerializeObject(user, serializerSettings);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType);
|
||||
Assert.Equal("{\"Message\":\"hello\"}", content);
|
||||
Assert.Equal("{\"message\":\"hello\"}", content);
|
||||
}
|
||||
|
||||
// Using an Accept header can't force Json to not be Json. If your accept header doesn't jive with the
|
||||
|
|
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType);
|
||||
Assert.Equal("{\"Message\":\"hello\"}", content);
|
||||
Assert.Equal("{\"message\":\"hello\"}", content);
|
||||
}
|
||||
|
||||
// If the object is null, it will get formatted as JSON. NOT as a 204/NoContent
|
||||
|
|
@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("application/message+json", response.Content.Headers.ContentType.MediaType);
|
||||
Assert.Equal("{\"Message\":\"hello\"}", content);
|
||||
Assert.Equal("{\"message\":\"hello\"}", content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
Assert.NotNull(response.Content.Headers.ContentType);
|
||||
Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType.ToString());
|
||||
var responseData = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("{\"Id\":10,\"Name\":\"John\"}", responseData);
|
||||
Assert.Equal("{\"id\":10,\"name\":\"John\"}", responseData);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
|
|
@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
"<RespectBrowserAcceptHeaderController.Employee xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"" +
|
||||
" xmlns=\"http://schemas.datacontract.org/2004/07/FormatterWebSite.Controllers\"><Id>35</Id><Name>Jimmy" +
|
||||
"</Name></RespectBrowserAcceptHeaderController.Employee>";
|
||||
var expectedResponseData = @"{""Id"":35,""Name"":""Jimmy""}";
|
||||
var expectedResponseData = @"{""id"":35,""name"":""Jimmy""}";
|
||||
var request = RequestWithAccept("http://localhost/RespectBrowserAcceptHeader/CreateEmployee", acceptHeader);
|
||||
request.Content = new StringContent(requestData, Encoding.UTF8, "application/xml");
|
||||
request.Method = HttpMethod.Post;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Ambiguous, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("{\"name\":\"Test User\"}", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("{\"name\":\"Test User\"}", content);
|
||||
Assert.Equal("5", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("{\"name\":\"Test User\"}", content);
|
||||
Assert.Equal("/api/Blog/ActionResult/GetUser/5", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("{\"name\":\"Test User\"}", content);
|
||||
Assert.Equal("http://localhost/api/Blog/ActionResult/5", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("{\"name\":\"Test User\"}", content);
|
||||
Assert.Equal("/api/Blog/ActionResult/GetUser/5", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("{\"name\":\"Test User\"}", content);
|
||||
Assert.Equal("http://localhost/api/Blog/ActionResult/GetUser/5", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("{\"name\":\"Test User\"}", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -182,7 +182,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var expected =
|
||||
"{" + Environment.NewLine +
|
||||
" \"Name\": \"Test User\"" + Environment.NewLine +
|
||||
" \"name\": \"Test User\"" + Environment.NewLine +
|
||||
"}";
|
||||
|
||||
// Act
|
||||
|
|
@ -200,7 +200,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
// Arrange
|
||||
var expected =
|
||||
"{" + Environment.NewLine +
|
||||
" \"Name\": \"Test User\"" + Environment.NewLine +
|
||||
" \"name\": \"Test User\"" + Environment.NewLine +
|
||||
"}";
|
||||
|
||||
// Act
|
||||
|
|
@ -242,7 +242,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("{\"name\":\"Test User\"}", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("{\"Id\":5,\"Name\":\"Test Employee\"}", content);
|
||||
Assert.Equal("{\"id\":5,\"name\":\"Test Employee\"}", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("{\"Id\":5,\"Name\":\"Test Employee\"}", content);
|
||||
Assert.Equal("{\"id\":5,\"name\":\"Test Employee\"}", content);
|
||||
}
|
||||
|
||||
// name is read from the url - and the rest from the body (formatters)
|
||||
|
|
@ -193,7 +193,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("{\"Id\":5,\"Name\":\"Name_Override\"}", content);
|
||||
Assert.Equal("{\"id\":5,\"name\":\"Name_Override\"}", content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
|||
using BasicWebSite.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace BasicWebSite.Controllers
|
||||
{
|
||||
|
|
@ -65,20 +65,21 @@ namespace BasicWebSite.Controllers
|
|||
{
|
||||
Person person = new Person
|
||||
{
|
||||
Id = 9000,
|
||||
Name = "John <b>Smith</b>"
|
||||
id = 9000,
|
||||
FullName = "John <b>Smith</b>"
|
||||
};
|
||||
|
||||
return View(person);
|
||||
}
|
||||
|
||||
public IActionResult JsonHelperWithSettingsInView()
|
||||
public IActionResult JsonHelperWithSettingsInView(bool snakeCase)
|
||||
{
|
||||
Person person = new Person
|
||||
{
|
||||
Id = 9000,
|
||||
Name = "John <b>Smith</b>"
|
||||
id = 9000,
|
||||
FullName = "John <b>Smith</b>"
|
||||
};
|
||||
ViewData["naming"] = snakeCase ? (NamingStrategy)new SnakeCaseNamingStrategy() : new DefaultNamingStrategy();
|
||||
|
||||
return View(person);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ namespace BasicWebSite.Models
|
|||
{
|
||||
public class Person
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public string FullName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,10 @@
|
|||
@using Newtonsoft.Json.Serialization
|
||||
@{
|
||||
var settings = JsonSerializerSettingsProvider.CreateSerializerSettings();
|
||||
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
||||
settings.ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = (NamingStrategy)(ViewData["naming"]),
|
||||
};
|
||||
}
|
||||
<script type="text/javascript">
|
||||
var json = @Json.Serialize(Model, settings);
|
||||
|
|
|
|||
Loading…
Reference in New Issue