Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
[Fixes #2506] Added overload to Controller.Json to accept JsonSeriali…
Browse files Browse the repository at this point in the history
…zerSettings
  • Loading branch information
ajaybhargavb committed May 8, 2015
1 parent bd03142 commit e1f6873
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Microsoft.Framework.Internal;
using Microsoft.Framework.OptionsModel;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;

namespace Microsoft.AspNet.Mvc
{
Expand All @@ -35,6 +36,16 @@ public JsonResult(object value)
{
}

/// <summary>
/// Creates a new <see cref="JsonResult"/> with the given <paramref name="data"/>.
/// </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, JsonSerializerSettings serializerSettings)
: this(value, formatter: new JsonOutputFormatter { SerializerSettings = serializerSettings })
{
}

/// <summary>
/// Creates a new <see cref="JsonResult"/> with the given <paramref name="data"/>.
/// </summary>
Expand All @@ -48,6 +59,7 @@ public JsonResult(object value, IOutputFormatter formatter)
ContentTypes = new List<MediaTypeHeaderValue>();
}


/// <summary>
/// Gets or sets the list of supported Content-Types.
/// </summary>
Expand Down
23 changes: 23 additions & 0 deletions src/Microsoft.AspNet.Mvc.Core/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Microsoft.AspNet.Routing;
using Microsoft.Framework.Internal;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;

namespace Microsoft.AspNet.Mvc
{
Expand Down Expand Up @@ -399,6 +400,28 @@ public virtual JsonResult Json(object data)
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"/>
/// to JSON format for the response.</returns>
/// <remarks>It is recommended to cache the <see cref="JsonSerializerSettings"/> instance for the action
/// since it creates a new contract for every instance.</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>
Expand Down
19 changes: 19 additions & 0 deletions test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using Microsoft.AspNet.WebUtilities;
#if DNX451
using Moq;
using Newtonsoft.Json;
#endif
using Xunit;

Expand Down Expand Up @@ -1031,6 +1032,24 @@ public void Controller_Json_WithParameterValue_SetsResultData()
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()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.AspNet.Routing;
using Microsoft.AspNet.WebUtilities;
using Moq;
using Newtonsoft.Json;
using Xunit;

namespace Microsoft.AspNet.Mvc
Expand Down Expand Up @@ -209,6 +210,28 @@ public void ControllerJson_InvokedInUnitTests()
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(model.GetType(), jsonResult.Value);
var jsonFormatter = jsonResult.Formatter as JsonOutputFormatter;
Assert.Same(serializerSettings, jsonFormatter.SerializerSettings);
}

[Fact]
public void ControllerHttpNotFound_InvokedInUnitTests()
{
Expand Down Expand Up @@ -590,6 +613,11 @@ public IActionResult Json_Action(object data)
return Json(data);
}

public IActionResult JsonWithSerializerSettings_Action(object data, JsonSerializerSettings serializerSettings)
{
return Json(data, serializerSettings);
}

public IActionResult Redirect_Action(string url)
{
return Redirect(url);
Expand Down
27 changes: 27 additions & 0 deletions test/Microsoft.AspNet.Mvc.Core.Test/JsonResultTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Microsoft.Framework.OptionsModel;
using Microsoft.Net.Http.Headers;
using Moq;
using Newtonsoft.Json;
using Xunit;

namespace Microsoft.AspNet.Mvc
Expand All @@ -24,6 +25,9 @@ public class JsonResultTest
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()
{
Expand Down Expand Up @@ -154,6 +158,29 @@ public async Task ExecuteResultAsync_UsesPassedInFormatter_ContentTypeSpecified(
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]
Expand Down
24 changes: 24 additions & 0 deletions test/Microsoft.AspNet.Mvc.FunctionalTests/JsonResultTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,30 @@ public async Task JsonResult_CustomFormatter_Conneg_Fails(string mediaType)
Assert.Equal("{\"message\":\"hello\"}", content);
}

[Theory]
[InlineData("application/json")]
[InlineData("text/json")]
public async Task JsonResult_CustomSerializerSettings_Conneg(string mediaType)
{
// 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);
request.Headers.TryAddWithoutValidation("Accept", mediaType);

// Act
var response = await client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();

// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(mediaType, response.Content.Headers.ContentType.MediaType);
Assert.Equal("{\"message\":\"hello\"}", content);
}

[Fact]
public async Task JsonResult_CustomContentType()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Microsoft.AspNet.Mvc;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace BasicWebSite.Controllers
Expand Down Expand Up @@ -32,6 +33,14 @@ public JsonResult CustomContentType()
return result;
}

public JsonResult CustomSerializerSettings()
{
var serializerSettings = new JsonSerializerSettings();
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

return new JsonResult(new { Message = "hello" }, serializerSettings);
}

public JsonResult Null()
{
return Json(null);
Expand Down

0 comments on commit e1f6873

Please sign in to comment.