[Fixes #2506] Added overload to Controller.Json to accept JsonSerializerSettings

This commit is contained in:
Ajay Bhargav Baaskaran 2015-05-08 13:17:53 -07:00
parent 131096ff61
commit d6012d4297
7 changed files with 149 additions and 3 deletions

View File

@ -9,6 +9,7 @@ using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.OptionsModel;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
namespace Microsoft.AspNet.Mvc
{
@ -27,7 +28,7 @@ namespace Microsoft.AspNet.Mvc
};
/// <summary>
/// Creates a new <see cref="JsonResult"/> with the given <paramref name="data"/>.
/// Creates a new <see cref="JsonResult"/> with the given <paramref name="value"/>.
/// </summary>
/// <param name="value">The value to format as JSON.</param>
public JsonResult(object value)
@ -36,7 +37,18 @@ namespace Microsoft.AspNet.Mvc
}
/// <summary>
/// Creates a new <see cref="JsonResult"/> with the given <paramref name="data"/>.
/// Creates a new <see cref="JsonResult"/> with the given <paramref name="value"/>.
/// </summary>
/// <param name="value">The value to format as JSON.</param>
/// <param name="serializerSettings">The <see cref="JsonSerializerSettings"/> to be used by
/// the formatter.</param>
public JsonResult(object value, [NotNull] JsonSerializerSettings serializerSettings)
: this(value, formatter: new JsonOutputFormatter { SerializerSettings = serializerSettings })
{
}
/// <summary>
/// Creates a new <see cref="JsonResult"/> with the given <paramref name="value"/>.
/// </summary>
/// <param name="value">The value to format as JSON.</param>
/// <param name="formatter">The formatter to use, or <c>null</c> to choose a formatter dynamically.</param>

View File

@ -15,6 +15,7 @@ using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.Internal;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
namespace Microsoft.AspNet.Mvc
{
@ -399,6 +400,29 @@ namespace Microsoft.AspNet.Mvc
return new JsonResult(data);
}
/// <summary>
/// Creates a <see cref="JsonResult"/> object that serializes the specified <paramref name="data"/> object
/// to JSON.
/// </summary>
/// <param name="data">The object to serialize.</param>
/// <param name="serializerSettings">The <see cref="JsonSerializerSettings"/> to be used by
/// the formatter.</param>
/// <returns>The created <see cref="JsonResult"/> that serializes the specified <paramref name="data"/>
/// as JSON format for the response.</returns>
/// <remarks>Callers should cache an instance of <see cref="JsonSerializerSettings"/> to avoid
/// recreating cached data with each call.</remarks>
[NonAction]
public virtual JsonResult Json(object data, [NotNull] JsonSerializerSettings serializerSettings)
{
var disposableValue = data as IDisposable;
if (disposableValue != null)
{
Response.OnResponseCompleted(_ => disposableValue.Dispose(), state: null);
}
return new JsonResult(data, serializerSettings);
}
/// <summary>
/// Creates a <see cref="RedirectResult"/> object that redirects to the specified <paramref name="url"/>.
/// </summary>

View File

@ -19,6 +19,7 @@ using Microsoft.AspNet.WebUtilities;
#if DNX451
using Moq;
#endif
using Newtonsoft.Json;
using Xunit;
namespace Microsoft.AspNet.Mvc.Test
@ -1031,6 +1032,24 @@ namespace Microsoft.AspNet.Mvc.Test
Assert.Same(data, actualJsonResult.Value);
}
[Fact]
public void Controller_Json_WithParameterValueAndSerializerSettings_SetsRespectiveValues()
{
// Arrange
var controller = new TestableController();
var data = new object();
var serializerSettings = new JsonSerializerSettings();
// Act
var actualJsonResult = controller.Json(data, serializerSettings);
// Assert
Assert.IsType<JsonResult>(actualJsonResult);
Assert.Same(data, actualJsonResult.Value);
var jsonFormatter = actualJsonResult.Formatter as JsonOutputFormatter;
Assert.Same(serializerSettings, jsonFormatter.SerializerSettings);
}
[Fact]
public void Controller_Json_IDisposableObject_RegistersForDispose()
{

View File

@ -10,6 +10,7 @@ using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Routing;
using Microsoft.AspNet.WebUtilities;
using Moq;
using Newtonsoft.Json;
using Xunit;
namespace Microsoft.AspNet.Mvc
@ -194,7 +195,7 @@ namespace Microsoft.AspNet.Mvc
var jsonResult = Assert.IsType<JsonResult>(result);
Assert.NotNull(jsonResult.Value);
Assert.Same(model, jsonResult.Value);
Assert.IsType(model.GetType(), jsonResult.Value);
Assert.IsType<MyModel>(jsonResult.Value);
// Arrange
controller = new TestabilityController();
@ -209,6 +210,28 @@ namespace Microsoft.AspNet.Mvc
Assert.Null(jsonResult.Value);
}
[Fact]
public void ControllerJsonWithSerializerSettings_InvokedInUnitTests()
{
// Arrange
var controller = new TestabilityController();
var model = new MyModel() { Property1 = "Property_1" };
var serializerSettings = new JsonSerializerSettings();
// Act
var result = controller.JsonWithSerializerSettings_Action(model, serializerSettings);
// Assert
Assert.NotNull(result);
var jsonResult = Assert.IsType<JsonResult>(result);
Assert.NotNull(jsonResult.Value);
Assert.Same(model, jsonResult.Value);
Assert.IsType<MyModel>(jsonResult.Value);
var jsonFormatter = jsonResult.Formatter as JsonOutputFormatter;
Assert.Same(serializerSettings, jsonFormatter.SerializerSettings);
}
[Fact]
public void ControllerHttpNotFound_InvokedInUnitTests()
{
@ -590,6 +613,11 @@ namespace Microsoft.AspNet.Mvc
return Json(data);
}
public IActionResult JsonWithSerializerSettings_Action(object data, JsonSerializerSettings serializerSettings)
{
return Json(data, serializerSettings);
}
public IActionResult Redirect_Action(string url)
{
return Redirect(url);

View File

@ -15,6 +15,7 @@ using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Net.Http.Headers;
using Moq;
using Newtonsoft.Json;
using Xunit;
namespace Microsoft.AspNet.Mvc
@ -24,6 +25,9 @@ namespace Microsoft.AspNet.Mvc
private static readonly byte[] _abcdUTF8Bytes
= new byte[] { 123, 34, 102, 111, 111, 34, 58, 34, 97, 98, 99, 100, 34, 125 };
private static readonly byte[] _abcdIndentedUTF8Bytes
= new byte[] { 123, 13, 10, 32, 32, 34, 102, 111, 111, 34, 58, 32, 34, 97, 98, 99, 100, 34, 13, 10, 125 };
[Fact]
public async Task ExecuteResultAsync_OptionsFormatter_WithoutBOM()
{
@ -154,6 +158,29 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal("application/hal+json; charset=utf-8", context.Response.ContentType);
}
[Fact]
public async Task ExecuteResultAsync_UsesPassedInSerializerSettings()
{
// Arrange
var expected = _abcdIndentedUTF8Bytes;
var context = GetHttpContext();
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
var serializerSettings = new JsonSerializerSettings();
serializerSettings.Formatting = Formatting.Indented;
var result = new JsonResult(new { foo = "abcd" }, serializerSettings);
// Act
await result.ExecuteResultAsync(actionContext);
var written = GetWrittenBytes(context);
// Assert
Assert.Equal(expected, written);
Assert.Equal("application/json; charset=utf-8", context.Response.ContentType);
}
// If no formatter in options can match the given content-types, then use the one registered
// in services
[Fact]

View File

@ -161,6 +161,26 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
Assert.Equal("{\"message\":\"hello\"}", content);
}
[Fact]
public async Task JsonResult_Uses_CustomSerializerSettings()
{
// Arrange
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
var client = server.CreateClient();
var url = "http://localhost/JsonResult/CustomSerializerSettings";
var request = new HttpRequestMessage(HttpMethod.Get, url);
// Act
var response = await client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("{\"message\":\"hello\"}", content);
}
[Fact]
public async Task JsonResult_CustomContentType()
{

View File

@ -3,12 +3,15 @@
using Microsoft.AspNet.Mvc;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace BasicWebSite.Controllers
{
public class JsonResultController : Controller
{
private static JsonSerializerSettings _customSerializerSettings;
public JsonResult Plain()
{
return Json(new { Message = "hello" });
@ -32,6 +35,19 @@ namespace BasicWebSite.Controllers
return result;
}
public JsonResult CustomSerializerSettings()
{
if (_customSerializerSettings == null)
{
_customSerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
}
return Json(new { Message = "hello" }, _customSerializerSettings);
}
public JsonResult Null()
{
return Json(null);