Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ internal static void AddMvcCoreServices(IServiceCollection services)
services.TryAddSingleton<IActionResultExecutor<RedirectToRouteResult>, RedirectToRouteResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<RedirectToPageResult>, RedirectToPageResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<ContentResult>, ContentResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<JsonResult>, SystemTextJsonResultExecutor>();
services.TryAddSingleton<IClientErrorFactory, ProblemDetailsClientErrorFactory>();

//
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
// 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.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{
public class JsonResultTest : IClassFixture<MvcTestFixture<BasicWebSite.StartupWithoutEndpointRouting>>
public class JsonResultWithNewtonsoftJsonTest : IClassFixture<MvcTestFixture<BasicWebSite.StartupWithNewtonsoftJson>>
{
public JsonResultTest(MvcTestFixture<BasicWebSite.StartupWithoutEndpointRouting> fixture)
private IServiceCollection _serviceCollection;

public JsonResultWithNewtonsoftJsonTest(MvcTestFixture<BasicWebSite.StartupWithNewtonsoftJson> fixture)
{
Client = fixture.CreateDefaultClient();
var factory = fixture.Factories.FirstOrDefault() ?? fixture.WithWebHostBuilder(b => b.UseStartup<BasicWebSite.StartupWithNewtonsoftJson>());
factory = factory.WithWebHostBuilder(b => b.ConfigureTestServices(serviceCollection => _serviceCollection = serviceCollection));

Client = factory.CreateDefaultClient();
}

public HttpClient Client { get; }
Expand All @@ -21,7 +30,7 @@ public JsonResultTest(MvcTestFixture<BasicWebSite.StartupWithoutEndpointRouting>
public async Task JsonResult_UsesDefaultContentType()
{
// Arrange
var url = "http://localhost/JsonResult/Plain";
var url = "http://localhost/JsonResultWithNewtonsoftJson/Plain";
var request = new HttpRequestMessage(HttpMethod.Get, url);

// Act
Expand All @@ -42,7 +51,7 @@ public async Task JsonResult_UsesDefaultContentType()
public async Task JsonResult_Conneg_Fails(string mediaType)
{
// Arrange
var url = "http://localhost/JsonResult/Plain";
var url = "http://localhost/JsonResultWithNewtonsoftJson/Plain";
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.TryAddWithoutValidation("Accept", mediaType);

Expand All @@ -61,7 +70,7 @@ public async Task JsonResult_Conneg_Fails(string mediaType)
public async Task JsonResult_Null()
{
// Arrange
var url = "http://localhost/JsonResult/Null";
var url = "http://localhost/JsonResultWithNewtonsoftJson/Null";
var request = new HttpRequestMessage(HttpMethod.Get, url);

// Act
Expand All @@ -79,7 +88,7 @@ public async Task JsonResult_Null()
public async Task JsonResult_String()
{
// Arrange
var url = "http://localhost/JsonResult/String";
var url = "http://localhost/JsonResultWithNewtonsoftJson/String";
var request = new HttpRequestMessage(HttpMethod.Get, url);

// Act
Expand All @@ -96,7 +105,7 @@ public async Task JsonResult_String()
public async Task JsonResult_Uses_CustomSerializerSettings()
{
// Arrange
var url = "http://localhost/JsonResult/CustomSerializerSettings";
var url = "http://localhost/JsonResultWithNewtonsoftJson/CustomSerializerSettings";
var request = new HttpRequestMessage(HttpMethod.Get, url);

// Act
Expand All @@ -112,7 +121,7 @@ public async Task JsonResult_Uses_CustomSerializerSettings()
public async Task JsonResult_CustomContentType()
{
// Arrange
var url = "http://localhost/JsonResult/CustomContentType";
var url = "http://localhost/JsonResultWithNewtonsoftJson/CustomContentType";
var request = new HttpRequestMessage(HttpMethod.Get, url);

// Act
Expand All @@ -125,4 +134,4 @@ public async Task JsonResult_CustomContentType()
Assert.Equal("{\"message\":\"hello\"}", content);
}
}
}
}
137 changes: 137 additions & 0 deletions src/Mvc/test/Mvc.FunctionalTests/JsonResultWithSystemTextJsonTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// 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.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{
public class JsonResultWithSystemTextJsonTest : IClassFixture<MvcTestFixture<BasicWebSite.StartupWithSystemTextJson>>
{
private IServiceCollection _serviceCollection;

public JsonResultWithSystemTextJsonTest(MvcTestFixture<BasicWebSite.StartupWithSystemTextJson> fixture)
{
var factory = fixture.Factories.FirstOrDefault() ?? fixture.WithWebHostBuilder(b => b.UseStartup<BasicWebSite.StartupWithSystemTextJson>());
factory = factory.WithWebHostBuilder(b => b.ConfigureTestServices(serviceCollection => _serviceCollection = serviceCollection));

Client = factory.CreateDefaultClient();
}

public HttpClient Client { get; }

[Fact]
public async Task JsonResult_UsesDefaultContentType()
{
// Arrange
var url = "http://localhost/JsonResultWithSystemTextJson/Plain";
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("application/json", response.Content.Headers.ContentType.MediaType);
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
// formatters/content-type configured on the result it will be ignored.
[Theory]
[InlineData("application/xml")]
[InlineData("text/xml")]
public async Task JsonResult_Conneg_Fails(string mediaType)
{
// Arrange
var url = "http://localhost/JsonResultWithSystemTextJson/Plain";
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("application/json", response.Content.Headers.ContentType.MediaType);
Assert.Equal("{\"message\":\"hello\"}", content);
}

// If the object is null, it will get formatted as JSON. NOT as a 204/NoContent
[Fact]
public async Task JsonResult_Null()
{
// Arrange
var url = "http://localhost/JsonResultWithSystemTextJson/Null";
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("application/json", response.Content.Headers.ContentType.MediaType);
Assert.Equal("null", content);
}

// If the object is a string, it will get formatted as JSON. NOT as text/plain.
[Fact]
public async Task JsonResult_String()
{
// Arrange
var url = "http://localhost/JsonResultWithSystemTextJson/String";
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("application/json", response.Content.Headers.ContentType.MediaType);
Assert.Equal("\"hello\"", content);
}

[Fact]
public async Task JsonResult_Uses_CustomSerializerSettings()
{
// Arrange
var url = "http://localhost/JsonResultWithSystemTextJson/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()
{
// Arrange
var url = "http://localhost/JsonResultWithSystemTextJson/CustomContentType";
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("application/message+json", response.Content.Headers.ContentType.MediaType);
Assert.Equal("{\"message\":\"hello\"}", content);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

namespace BasicWebSite.Controllers
{
public class JsonResultController : Controller
public class JsonResultWithNewtonsoftJsonController : Controller
{
private static readonly JsonSerializerSettings _customSerializerSettings;

static JsonResultController()
static JsonResultWithNewtonsoftJsonController()
{
_customSerializerSettings = JsonSerializerSettingsProvider.CreateSerializerSettings();
_customSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
Expand Down Expand Up @@ -45,4 +45,4 @@ public JsonResult String()
return new JsonResult("hello");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// 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.Text.Json;
using Microsoft.AspNetCore.Mvc;

namespace BasicWebSite.Controllers
{
public class JsonResultWithSystemTextJsonController : Controller
{
private static readonly JsonSerializerOptions _customSerializerSettings;

static JsonResultWithSystemTextJsonController()
{
_customSerializerSettings = new JsonSerializerOptions();
}

public JsonResult Plain()
{
return new JsonResult(new { Message = "hello" });
}

public JsonResult CustomContentType()
{
var result = new JsonResult(new { Message = "hello" });
result.ContentType = "application/message+json";
return result;
}

public JsonResult CustomSerializerSettings()
{
return new JsonResult(new { Message = "hello" }, _customSerializerSettings);
}

public JsonResult Null()
{
return new JsonResult(null);
}

public JsonResult String()
{
return new JsonResult("hello");
}
}
}
29 changes: 29 additions & 0 deletions src/Mvc/test/WebSites/BasicWebSite/StartupWithNewtonsoftJson.cs
Original file line number Diff line number Diff line change
@@ -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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;

namespace BasicWebSite
{
public class StartupWithNewtonsoftJson
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest)
.AddNewtonsoftJson();
}

public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();

app.UseRouting();

app.UseEndpoints((endpoints) => endpoints.MapDefaultControllerRoute());
}
}
}
28 changes: 28 additions & 0 deletions src/Mvc/test/WebSites/BasicWebSite/StartupWithSystemTextJson.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;

namespace BasicWebSite
{
public class StartupWithSystemTextJson
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
}

public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();

app.UseRouting();

app.UseEndpoints((endpoints) => endpoints.MapDefaultControllerRoute());
}
}
}