diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ContentNegotiator/DefaultContentNegotiator.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ContentNegotiator/DefaultContentNegotiator.cs index 1883c03ee6..8ee0b6b222 100644 --- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ContentNegotiator/DefaultContentNegotiator.cs +++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ContentNegotiator/DefaultContentNegotiator.cs @@ -9,8 +9,6 @@ using System.Diagnostics; using System.Linq; using System.Net.Http.Headers; using System.Text; -using Microsoft.AspNet.Mvc; -using Microsoft.Extensions.Internal; namespace System.Net.Http.Formatting { @@ -85,14 +83,25 @@ namespace System.Net.Http.Formatting // We found a best formatter if (bestFormatterMatch != null) { - // Find the best character encoding for the selected formatter + var bestMediaType = bestFormatterMatch.MediaType; + + // Find the best character encoding for the selected formatter. var bestEncodingMatch = SelectResponseCharacterEncoding(request, bestFormatterMatch.Formatter); if (bestEncodingMatch != null) { - bestFormatterMatch.MediaType.CharSet = bestEncodingMatch.WebName; + // Clone media type value since this is not done defensively in this implementation. + // `MediaTypeHeaderValue` lacks a Clone() method in this runtime. Fortunately, this is the only + // update to an existing instance we need. + var clonedMediaType = new MediaTypeHeaderValue(bestMediaType.MediaType); + foreach (var parameter in bestMediaType.Parameters) + { + clonedMediaType.Parameters.Add(new NameValueHeaderValue(parameter.Name, parameter.Value)); + } + + bestMediaType = clonedMediaType; + bestMediaType.CharSet = bestEncodingMatch.WebName; } - var bestMediaType = bestFormatterMatch.MediaType; var bestFormatter = bestFormatterMatch.Formatter.GetPerRequestFormatterInstance(type, request, bestMediaType); return new ContentNegotiationResult(bestFormatter, bestMediaType); diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/FilteredDefaultAssemblyProviderFixtureOfT.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/FilteredDefaultAssemblyProviderFixtureOfT.cs index 737b2aaa7d..d4ac0cb6e4 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/FilteredDefaultAssemblyProviderFixtureOfT.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/FilteredDefaultAssemblyProviderFixtureOfT.cs @@ -5,8 +5,8 @@ using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNet.Mvc.Infrastructure; -using Microsoft.Extensions.PlatformAbstractions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.PlatformAbstractions; namespace Microsoft.AspNet.Mvc.FunctionalTests { @@ -15,9 +15,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests { protected override void AddAdditionalServices(IServiceCollection services) { - // TestHelper.CreateServer normally replaces the DefaultAssemblyProvider with a provider that limits the - // set of candidate assemblies to the executing application. Switch it back to using a filtered default - // assembly provider. + // MvcTestFixture normally replaces the DefaultAssemblyProvider with an IAssemblyProvider + // implementation that limits the set of candidate assemblies to the executing application. Switch it back + // to using a filtered default assembly provider. services.AddTransient(); } diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/TestHelper.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/TestHelper.cs deleted file mode 100644 index 6541dd3541..0000000000 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/TestHelper.cs +++ /dev/null @@ -1,125 +0,0 @@ -// 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.IO; -using System.Reflection; -using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Hosting; -using Microsoft.AspNet.Mvc.Infrastructure; -using Microsoft.AspNet.TestHost; -using Microsoft.Extensions.PlatformAbstractions; -using Microsoft.Extensions.DependencyInjection; - -namespace Microsoft.AspNet.Mvc.FunctionalTests -{ - public static class TestHelper - { - // Path from Mvc\\test\\Microsoft.AspNet.Mvc.FunctionalTests - private static readonly string WebsitesDirectoryPath = Path.Combine("..", "WebSites"); - - public static TestServer CreateServer(Action builder, string applicationWebSiteName) - { - return CreateServer( - builder, - applicationWebSiteName, - applicationPath: null, - configureServices: (Action)null); - } - - public static TestServer CreateServer( - Action builder, - string applicationWebSiteName, - Action configureServices) - { - return CreateServer( - builder, - applicationWebSiteName, - applicationPath: null, - configureServices: configureServices); - } - - private static TestServer CreateServer( - Action builder, - string applicationWebSiteName, - string applicationPath, - Action configureServices) - { - return TestServer.Create( - builder, - services => AddTestServices(services, applicationWebSiteName, applicationPath, configureServices)); - } - - private static void AddTestServices( - IServiceCollection services, - string applicationWebSiteName, - string applicationPath, - Action configureServices) - { - applicationPath = applicationPath ?? WebsitesDirectoryPath; - - // Get current IApplicationEnvironment; likely added by the host. - var provider = services.BuildServiceProvider(); - var originalEnvironment = provider.GetRequiredService(); - - // When an application executes in a regular context, the application base path points to the root - // directory where the application is located, for example MvcSample.Web. However, when executing - // an application as part of a test, the ApplicationBasePath of the IApplicationEnvironment points - // to the root folder of the test project. - // To compensate for this, we need to calculate the original path and override the application - // environment value so that components like the view engine work properly in the context of the - // test. - var applicationBasePath = CalculateApplicationBasePath( - originalEnvironment, - applicationWebSiteName, - applicationPath); - var environment = new TestApplicationEnvironment( - originalEnvironment, - applicationWebSiteName, - applicationBasePath); - services.AddInstance(environment); - var hostingEnvironment = new HostingEnvironment(); - hostingEnvironment.Initialize(applicationBasePath, config: null); - services.AddInstance(hostingEnvironment); - - // Injecting a custom assembly provider. Overrides AddMvc() because that uses TryAdd(). - var assemblyProvider = CreateAssemblyProvider(applicationWebSiteName); - services.AddInstance(assemblyProvider); - - // Avoid using pooled memory, we don't have a guarantee that our services will get disposed. - services.AddInstance(new TestHttpResponseStreamWriterFactory()); - - if (configureServices != null) - { - configureServices(services); - } - } - - // Calculate the path relative to the application base path. - private static string CalculateApplicationBasePath( - IApplicationEnvironment appEnvironment, - string applicationWebSiteName, - string websitePath) - { - // Mvc/test/WebSites/applicationWebSiteName - return Path.GetFullPath( - Path.Combine(appEnvironment.ApplicationBasePath, websitePath, applicationWebSiteName)); - } - - private static IAssemblyProvider CreateAssemblyProvider(string siteName) - { - // Creates a service type that will limit MVC to only the controllers in the test site. - // We only want this to happen when running in-process. - var assembly = Assembly.Load(new AssemblyName(siteName)); - var provider = new StaticAssemblyProvider - { - CandidateAssemblies = - { - assembly, - }, - }; - - return provider; - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/WebApiCompatShimBasicTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/WebApiCompatShimBasicTest.cs index 5755180011..d3df00c508 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/WebApiCompatShimBasicTest.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/WebApiCompatShimBasicTest.cs @@ -10,10 +10,8 @@ using System.Net.Http.Formatting; using System.Net.Http.Headers; using System.Threading.Tasks; using System.Web.Http; -using Microsoft.AspNet.Builder; using Microsoft.AspNet.Testing; using Microsoft.AspNet.Testing.xunit; -using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Xunit; @@ -21,11 +19,6 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests { public class WebApiCompatShimBasicTest : IClassFixture> { - private const string SiteName = nameof(WebApiCompatShimWebSite); - private readonly Action _app = new WebApiCompatShimWebSite.Startup().Configure; - private readonly Action _configureServices = - new WebApiCompatShimWebSite.Startup().ConfigureServices; - public WebApiCompatShimBasicTest(MvcTestFixture fixture) { Client = fixture.Client; @@ -288,16 +281,13 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests public async Task ApiController_CreateResponse_Conneg(string accept, string mediaType) { // Arrange - var server = TestHelper.CreateServer(_app, SiteName, _configureServices); - var client = server.CreateClient(); - var request = new HttpRequestMessage( HttpMethod.Get, "http://localhost/api/Blog/HttpRequestMessage/GetUser"); request.Headers.Accept.ParseAdd(accept); // Act - var response = await client.SendAsync(request); + var response = await Client.SendAsync(request); var user = await response.Content.ReadAsAsync(); // Assert @@ -312,15 +302,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests public async Task ApiController_CreateResponse_HardcodedMediaType(string mediaType) { // Arrange - var server = TestHelper.CreateServer(_app, SiteName, _configureServices); - var client = server.CreateClient(); - var request = new HttpRequestMessage( HttpMethod.Get, "http://localhost/api/Blog/HttpRequestMessage/GetUser?mediaType=" + mediaType); // Act - var response = await client.SendAsync(request); + var response = await Client.SendAsync(request); var user = await response.Content.ReadAsAsync(); // Assert @@ -337,16 +324,13 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests public async Task ApiController_CreateResponse_Conneg_Error(string accept, string mediaType) { // Arrange - var server = TestHelper.CreateServer(_app, SiteName, _configureServices); - var client = server.CreateClient(); - var request = new HttpRequestMessage( HttpMethod.Get, "http://localhost/api/Blog/HttpRequestMessage/Fail"); request.Headers.Accept.ParseAdd(accept); // Act - var response = await client.SendAsync(request); + var response = await Client.SendAsync(request); var error = await response.Content.ReadAsAsync(); // Assert diff --git a/test/WebSites/WebApiCompatShimWebSite/Controllers/HttpRequestMessage/HttpRequestMessageController.cs b/test/WebSites/WebApiCompatShimWebSite/Controllers/HttpRequestMessage/HttpRequestMessageController.cs index 69d45d3b56..4f6ed6690e 100644 --- a/test/WebSites/WebApiCompatShimWebSite/Controllers/HttpRequestMessage/HttpRequestMessageController.cs +++ b/test/WebSites/WebApiCompatShimWebSite/Controllers/HttpRequestMessage/HttpRequestMessageController.cs @@ -70,7 +70,7 @@ namespace WebApiCompatShimWebSite if (mediaType == null) { - // This will perform content negotation + // This will perform content negotiation return Request.CreateResponse(HttpStatusCode.OK, user); } else @@ -93,7 +93,7 @@ namespace WebApiCompatShimWebSite [HttpGet] public HttpResponseMessage Fail() { - // This will perform content negotation + // This will perform content negotiation return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "It failed."); }