Update tests to latest compat switch

This commit is contained in:
Pranav K 2018-08-14 16:13:17 -07:00
parent e2de54a92d
commit 8eea0ad44c
60 changed files with 495 additions and 253 deletions

View File

@ -14,7 +14,7 @@ namespace MvcSandbox
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_2); services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Latest);
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

View File

@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing; using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Routing.Patterns;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Mvc.Internal namespace Microsoft.AspNetCore.Mvc.Internal
@ -59,10 +60,6 @@ namespace Microsoft.AspNetCore.Mvc.Internal
_httpContextInstance = new DefaultHttpContext() { RequestServices = serviceProvider }; _httpContextInstance = new DefaultHttpContext() { RequestServices = serviceProvider };
ConventionalEndpointInfos = new List<MvcEndpointInfo>(); ConventionalEndpointInfos = new List<MvcEndpointInfo>();
Extensions.Primitives.ChangeToken.OnChange(
GetCompositeChangeToken,
UpdateEndpoints);
} }
private List<Endpoint> CreateEndpoints() private List<Endpoint> CreateEndpoints()
@ -454,7 +451,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
return new CompositeChangeToken(changeTokens); return new CompositeChangeToken(changeTokens);
} }
public override IChangeToken GetChangeToken() => GetCompositeChangeToken(); public override IChangeToken GetChangeToken() => NullChangeToken.Singleton;
public override IReadOnlyList<Endpoint> Endpoints public override IReadOnlyList<Endpoint> Endpoints
{ {
@ -479,14 +476,6 @@ namespace Microsoft.AspNetCore.Mvc.Internal
} }
} }
private void UpdateEndpoints()
{
lock (_lock)
{
_endpoints = CreateEndpoints();
}
}
public List<MvcEndpointInfo> ConventionalEndpointInfos { get; } public List<MvcEndpointInfo> ConventionalEndpointInfos { get; }
private class SuppressLinkGenerationMetadata : ISuppressLinkGenerationMetadata { } private class SuppressLinkGenerationMetadata : ISuppressLinkGenerationMetadata { }

View File

@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
Assert.True(actionInvokerCalled); Assert.True(actionInvokerCalled);
} }
[Fact] [Fact(Skip = "https://github.com/aspnet/Routing/issues/722")]
public void GetChangeToken_MultipleChangeTokenProviders_ComposedResult() public void GetChangeToken_MultipleChangeTokenProviders_ComposedResult()
{ {
// Arrange // Arrange
@ -287,7 +287,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
actionDescriptorCollectionProviderMock.VerifyGet(m => m.ActionDescriptors, Times.Once); actionDescriptorCollectionProviderMock.VerifyGet(m => m.ActionDescriptors, Times.Once);
} }
[Fact] [Fact(Skip = "https://github.com/aspnet/Routing/issues/722")]
public void Endpoints_ChangeTokenTriggered_EndpointsRecreated() public void Endpoints_ChangeTokenTriggered_EndpointsRecreated()
{ {
// Arrange // Arrange

View File

@ -1087,7 +1087,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
}); });
} }
[Fact] [Fact(Skip = "https://github.com/aspnet/Routing/issues/722")]
public async Task ApiExplorer_Updates_WhenActionDescriptorCollectionIsUpdated() public async Task ApiExplorer_Updates_WhenActionDescriptorCollectionIsUpdated()
{ {
// Act - 1 // Act - 1

View File

@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal("From Header - HelloWorld", body); Assert.Equal("From Header - HelloWorld", body);
} }
[Fact] [Fact(Skip = "https://github.com/aspnet/Routing/issues/721")]
public async Task ActionModelSuppressedForPathMatching_CannotBeRouted() public async Task ActionModelSuppressedForPathMatching_CannotBeRouted()
{ {
// Arrange & Act // Arrange & Act

View File

@ -1,34 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class CorsEndpointRoutingTests : CorsTestsBase<CorsWebSite.StartupWithEndpointRouting> public class CorsEndpointRoutingTests : CorsTestsBase<CorsWebSite.Startup>
{ {
public CorsEndpointRoutingTests(MvcTestFixture<CorsWebSite.StartupWithEndpointRouting> fixture) public CorsEndpointRoutingTests(MvcTestFixture<CorsWebSite.Startup> fixture)
: base(fixture) : base(fixture)
{ {
} }
[Fact] // This intentionally returns a 405 with endpoint routing
public override async Task PreflightRequestOnNonCorsEnabledController_DoesNotMatchTheAction()
{
// Arrange
var request = new HttpRequestMessage(new HttpMethod("OPTIONS"), "http://localhost/NonCors/Post");
request.Headers.Add(CorsConstants.Origin, "http://example.com");
request.Headers.Add(CorsConstants.AccessControlRequestMethod, "POST");
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode);
} }
}
} }

View File

@ -1,13 +1,34 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class CorsTests : CorsTestsBase<CorsWebSite.Startup> public class CorsTests : CorsTestsBase<CorsWebSite.StartupWith21Compat>
{ {
public CorsTests(MvcTestFixture<CorsWebSite.Startup> fixture) public CorsTests(MvcTestFixture<CorsWebSite.StartupWith21Compat> fixture)
: base(fixture) : base(fixture)
{ {
} }
[Fact]
public override async Task PreflightRequestOnNonCorsEnabledController_DoesNotMatchTheAction()
{
// Arrange
var request = new HttpRequestMessage(new HttpMethod("OPTIONS"), "http://localhost/NonCors/Post");
request.Headers.Add(CorsConstants.Origin, "http://example.com");
request.Headers.Add(CorsConstants.AccessControlRequestMethod, "POST");
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
} }
} }

View File

@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
var response = await Client.SendAsync(request); var response = await Client.SendAsync(request);
// Assert // Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode);
} }
[Theory] [Theory]

View File

@ -10,9 +10,9 @@ using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class EndpointRoutingTest : RoutingTestsBase<RoutingWebSite.StartupWithEndpointRouting> public class EndpointRoutingTest : RoutingTestsBase<RoutingWebSite.Startup>
{ {
public EndpointRoutingTest(MvcTestFixture<RoutingWebSite.StartupWithEndpointRouting> fixture) public EndpointRoutingTest(MvcTestFixture<RoutingWebSite.Startup> fixture)
: base(fixture) : base(fixture)
{ {
} }
@ -32,26 +32,6 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.True(result); Assert.True(result);
} }
[Fact]
public override Task AttributeRoutedAction_InArea_StaysInArea_ActionDoesntExist()
{
// By design, this test cannot work in EndpointRouting world. This is because in case of old routing test
// when a link generation to an attribute routed controller with a non-existing action does not succeeed,
// the next route in the route collection is considered and since the next route in the route collection is
// a conventional area route, the old routing test succeeds. But this cannot happen in case of endpoint
// routing as the action does not exist to begin with.
return Task.CompletedTask;
}
[Fact]
public override Task ConventionalRoutedAction_InArea_StaysInArea()
{
// By design, this test cannot work in EndpointRouting world. In old routing test a link is being generated
// to a non-existing action on a controller which is in an area. In case of endpoint routing, we cannot
// generate links as the action does not exist to begin with.
return Task.CompletedTask;
}
[Fact] [Fact]
public async override Task RouteData_Routers_ConventionalRoute() public async override Task RouteData_Routers_ConventionalRoute()
{ {
@ -97,21 +77,6 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode); Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode);
} }
// Endpoint routing exposes HTTP 405s for HTTP method mismatches
[Fact]
public override async Task AttributeRoutedAction_MultipleRouteAttributes_RouteAttributeTemplatesIgnoredForOverrideActions()
{
// Arrange
var url = "http://localhost/api/v1/Maps";
// Act
var response = await Client.SendAsync(new HttpRequestMessage(new HttpMethod("POST"), url));
// Assert
Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode);
}
// Endpoint routing exposes HTTP 405s for HTTP method mismatches
[Theory] [Theory]
[MemberData(nameof(AttributeRoutedAction_MultipleRouteAttributes_WithMultipleHttpAttributes_RespectsConstraintsData))] [MemberData(nameof(AttributeRoutedAction_MultipleRouteAttributes_WithMultipleHttpAttributes_RespectsConstraintsData))]
public override async Task AttributeRoutedAction_MultipleRouteAttributes_WithMultipleHttpAttributes_RespectsConstraints( public override async Task AttributeRoutedAction_MultipleRouteAttributes_WithMultipleHttpAttributes_RespectsConstraints(

View File

@ -6,9 +6,7 @@ using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
@ -58,11 +56,9 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
public async Task AuthorizationPoliciesDoNotCombine_WithV2_0() public async Task AuthorizationPoliciesDoNotCombine_WithV2_0()
{ {
// Arrange & Act // Arrange & Act
var factory = Factory.WithWebHostBuilder( var client = Factory
builder => builder.ConfigureServices( .WithWebHostBuilder(builder => builder.UseStartup<SecurityWebSite.StartupWith20CompatAndGlobalDenyAnonymousFilter>())
services => services.Configure<MvcCompatibilityOptions>( .CreateDefaultClient();
options => options.CompatibilityVersion = CompatibilityVersion.Version_2_0)));
var client = factory.CreateDefaultClient();
var response = await client.PostAsync("http://localhost/Administration/SignInCookie2", null); var response = await client.PostAsync("http://localhost/Administration/SignInCookie2", null);
// Assert // Assert

View File

@ -10,8 +10,8 @@ using System.Net.Http.Headers;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using AngleSharp.Dom; using Microsoft.AspNetCore.Hosting;
using AngleSharp.Dom.Html; using Microsoft.AspNetCore.Mvc.Testing;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
@ -26,14 +26,21 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
MvcTestFixture<HtmlGenerationWebSite.Startup> fixture, MvcTestFixture<HtmlGenerationWebSite.Startup> fixture,
MvcEncodedTestFixture<HtmlGenerationWebSite.Startup> encodedFixture) MvcEncodedTestFixture<HtmlGenerationWebSite.Startup> encodedFixture)
{ {
Factory = fixture.Factories.FirstOrDefault() ?? fixture.WithWebHostBuilder(ConfigureWebHostBuilder);
Client = fixture.CreateDefaultClient(); Client = fixture.CreateDefaultClient();
EncodedClient = encodedFixture.CreateDefaultClient(); EncodedClient = encodedFixture.CreateDefaultClient();
} }
private static void ConfigureWebHostBuilder(IWebHostBuilder builder) =>
builder.UseStartup<HtmlGenerationWebSite.Startup>();
public HttpClient Client { get; } public HttpClient Client { get; }
public HttpClient EncodedClient { get; } public HttpClient EncodedClient { get; }
public WebApplicationFactory<HtmlGenerationWebSite.Startup> Factory { get; }
public static TheoryData<string, string> WebPagesData public static TheoryData<string, string> WebPagesData
{ {
get get
@ -131,6 +138,35 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
} }
} }
[Fact]
public async Task HtmlGenerationWebSite_LinkGeneration_With21CompatibilityBehavior()
{
// Arrange
var client = Factory
.WithWebHostBuilder(builder => builder.UseStartup<HtmlGenerationWebSite.StartupWith21CompatibilityBehavior>())
.CreateDefaultClient();
var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
var outputFile = "compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Index21Compat.html";
var expectedContent =
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
// Act
// The host is not important as everything runs in memory and tests are isolated from each other.
var response = await client.GetAsync("http://localhost/HtmlGeneration_Home/");
var responseContent = await response.Content.ReadAsStringAsync();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
responseContent = responseContent.Trim();
#if GENERATE_BASELINES
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
#else
Assert.Equal(expectedContent.Trim(), responseContent, ignoreLineEndingDifferences: true);
#endif
}
public static TheoryData<string, string> EncodedPagesData public static TheoryData<string, string> EncodedPagesData
{ {
get get

View File

@ -3,7 +3,6 @@
using System.Globalization; using System.Globalization;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -26,9 +25,6 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
var testSink = new TestSink(); var testSink = new TestSink();
var loggerFactory = new TestLoggerFactory(testSink, enabled: true); var loggerFactory = new TestLoggerFactory(testSink, enabled: true);
services.AddSingleton<ILoggerFactory>(loggerFactory); services.AddSingleton<ILoggerFactory>(loggerFactory);
services.Configure<MvcCompatibilityOptions>(
options => options.CompatibilityVersion = CompatibilityVersion.Version_2_1);
}); });
} }

View File

@ -919,7 +919,7 @@ Hello from /Pages/WithViewStart/Index.cshtml!";
{ {
// Arrange // Arrange
var expected = var expected =
@"Microsoft.AspNetCore.Mvc.Routing.UrlHelper @"Microsoft.AspNetCore.Mvc.Routing.EndpointRoutingUrlHelper
Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper`1[AspNetCore.InjectedPageProperties] Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper`1[AspNetCore.InjectedPageProperties]
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary`1[AspNetCore.InjectedPageProperties]"; Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary`1[AspNetCore.InjectedPageProperties]";

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Net; using System.Net;
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
@ -10,9 +11,9 @@ using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class RoutingTests : RoutingTestsBase<RoutingWebSite.Startup> public class RoutingTests : RoutingTestsBase<RoutingWebSite.StartupWith21Compat>
{ {
public RoutingTests(MvcTestFixture<RoutingWebSite.Startup> fixture) public RoutingTests(MvcTestFixture<RoutingWebSite.StartupWith21Compat> fixture)
: base(fixture) : base(fixture)
{ {
} }
@ -32,6 +33,62 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.False(result); Assert.False(result);
} }
// Legacy routing supports linking to actions that don't exist
[Fact]
public async Task AttributeRoutedAction_InArea_StaysInArea_ActionDoesntExist()
{
// Arrange
var url = LinkFrom("http://localhost/ContosoCorp/Trains")
.To(new { action = "Contact", controller = "Home", });
// Act
var response = await Client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
Assert.Equal("Rail", result.Controller);
Assert.Equal("Index", result.Action);
Assert.Equal("/Travel/Home/Contact", result.Link);
}
[Fact]
public async Task ConventionalRoutedAction_InArea_StaysInArea()
{
// Arrange
var url = LinkFrom("http://localhost/Travel/Flight").To(new { action = "Contact", controller = "Home", });
// Act
var response = await Client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
Assert.Equal("Flight", result.Controller);
Assert.Equal("Index", result.Action);
Assert.Equal("/Travel/Home/Contact", result.Link);
}
// Legacy routing returns 404 when an action does not support a HTTP method.
[Fact]
public override async Task AttributeRoutedAction_MultipleRouteAttributes_RouteAttributeTemplatesIgnoredForOverrideActions()
{
// Arrange
var url = "http://localhost/api/v1/Maps";
// Act
var response = await Client.SendAsync(new HttpRequestMessage(new HttpMethod("POST"), url));
// Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
[Fact] [Fact]
public async override Task RouteData_Routers_ConventionalRoute() public async override Task RouteData_Routers_ConventionalRoute()
{ {

View File

@ -340,7 +340,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
var response = await Client.SendAsync(new HttpRequestMessage(new HttpMethod("POST"), url)); var response = await Client.SendAsync(new HttpRequestMessage(new HttpMethod("POST"), url));
// Assert // Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode);
} }
[Theory] [Theory]
@ -1016,26 +1016,6 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal("/", result.Link); Assert.Equal("/", result.Link);
} }
[Fact]
public virtual async Task ConventionalRoutedAction_InArea_StaysInArea()
{
// Arrange
var url = LinkFrom("http://localhost/Travel/Flight").To(new { action = "Contact", controller = "Home", });
// Act
var response = await Client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
Assert.Equal("Flight", result.Controller);
Assert.Equal("Index", result.Action);
Assert.Equal("/Travel/Home/Contact", result.Link);
}
[Fact] [Fact]
public virtual async Task AttributeRoutedAction_LinkToArea() public virtual async Task AttributeRoutedAction_LinkToArea()
{ {
@ -1098,26 +1078,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal("/", result.Link); Assert.Equal("/", result.Link);
} }
[Fact]
public virtual async Task AttributeRoutedAction_InArea_StaysInArea_ActionDoesntExist()
{
// Arrange
var url = LinkFrom("http://localhost/ContosoCorp/Trains")
.To(new { action = "Contact", controller = "Home", });
// Act
var response = await Client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
Assert.Equal("Rail", result.Controller);
Assert.Equal("Index", result.Action);
Assert.Equal("/Travel/Home/Contact", result.Link);
}
[Fact] [Fact]
public virtual async Task AttributeRoutedAction_InArea_LinkToConventionalRoutedActionInArea() public virtual async Task AttributeRoutedAction_InArea_LinkToConventionalRoutedActionInArea()
@ -1280,13 +1241,13 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal(actionName, result.Action); Assert.Equal(actionName, result.Action);
} }
private static LinkBuilder LinkFrom(string url) protected static LinkBuilder LinkFrom(string url)
{ {
return new LinkBuilder(url); return new LinkBuilder(url);
} }
// See TestResponseGenerator in RoutingWebSite for the code that generates this data. // See TestResponseGenerator in RoutingWebSite for the code that generates this data.
private class RoutingResult protected class RoutingResult
{ {
public string[] ExpectedUrls { get; set; } public string[] ExpectedUrls { get; set; }
@ -1303,7 +1264,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
public string Link { get; set; } public string Link { get; set; }
} }
private class LinkBuilder protected class LinkBuilder
{ {
public LinkBuilder(string url) public LinkBuilder(string url)
{ {

View File

@ -9,9 +9,9 @@ using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class VersioningEndpointRoutingTests : VersioningTestsBase<VersioningWebSite.StartupWithEndpointRouting> public class VersioningEndpointRoutingTests : VersioningTestsBase<VersioningWebSite.Startup>
{ {
public VersioningEndpointRoutingTests(MvcTestFixture<VersioningWebSite.StartupWithEndpointRouting> fixture) public VersioningEndpointRoutingTests(MvcTestFixture<VersioningWebSite.Startup> fixture)
: base(fixture) : base(fixture)
{ {
} }

View File

@ -8,9 +8,9 @@ using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class VersioningTests : VersioningTestsBase<VersioningWebSite.Startup> public class VersioningTests : VersioningTestsBase<VersioningWebSite.StartupWith21Compat>
{ {
public VersioningTests(MvcTestFixture<VersioningWebSite.Startup> fixture) public VersioningTests(MvcTestFixture<VersioningWebSite.StartupWith21Compat> fixture)
: base(fixture) : base(fixture)
{ {
} }

View File

@ -13,7 +13,7 @@
<a href="HtmlEncode[[/]]">Default Controller</a> <a href="HtmlEncode[[/]]">Default Controller</a>
</div> </div>
<div> <div>
<a href="HtmlEncode[[/Product/Index#fragment]]">Product Index Fragment</a> <a href="HtmlEncode[[/HtmlGeneration_Product#fragment]]">Product Index Fragment</a>
</div> </div>
<div> <div>
<a href="HtmlEncode[[/HtmlGeneration_Product/Submit#fragment]]">Product Submit Fragment</a> <a href="HtmlEncode[[/HtmlGeneration_Product/Submit#fragment]]">Product Submit Fragment</a>
@ -39,32 +39,32 @@
</a> </a>
</div> </div>
<div> <div>
<a href="HtmlEncode[[/Customer/Customer#fragment]]">Customer Area Customer Index</a> <a href="HtmlEncode[[/Customer/HtmlGeneration_Customer#fragment]]">Customer Area Customer Index</a>
</div> </div>
<div> <div>
<a href="/Order/List">Href Order List</a> <a href="/Order/List">Href Order List</a>
</div> </div>
<div> <div>
<a href="HtmlEncode[[/NonExistentController]]">Non-existent Controller</a> <a href="">Non-existent Controller</a>
</div> </div>
<div> <div>
<a href="HtmlEncode[[/NonExistentController#fragment]]"> <a href="">
Non-existent Controller Fragment Non-existent Controller Fragment
</a> </a>
</div> </div>
<div> <div>
<a href="HtmlEncode[[/Order/NonExistentAction]]">Non-existent Action</a> <a href="">Non-existent Action</a>
</div> </div>
<div> <div>
<a id="Id" href="HtmlEncode[[http://somewhere/]]">Some Where</a> <a id="Id" href="HtmlEncode[[http://somewhere/]]">Some Where</a>
</div> </div>
<div> <div>
<a href="HtmlEncode[[unknown://localhost/NoControll#fragment]]"> <a href="">
Unknown Protocol Non-existent Controller Fragment Unknown Protocol Non-existent Controller Fragment
</a> </a>
</div> </div>
<div> <div>
<a href="HtmlEncode[[/Product/Submit?area=NonExistentArea&id=1#fragment]]">Product Route Non-existent Area Parameter</a> <a href="">Product Route Non-existent Area Parameter</a>
</div> </div>
<div> <div>
<a href="">Non-existent Area</a> <a href="">Non-existent Area</a>

View File

@ -13,7 +13,7 @@
<a href="/">Default Controller</a> <a href="/">Default Controller</a>
</div> </div>
<div> <div>
<a href="/Product/Index#fragment">Product Index Fragment</a> <a href="/HtmlGeneration_Product#fragment">Product Index Fragment</a>
</div> </div>
<div> <div>
<a href="/HtmlGeneration_Product/Submit#fragment">Product Submit Fragment</a> <a href="/HtmlGeneration_Product/Submit#fragment">Product Submit Fragment</a>
@ -39,32 +39,32 @@
</a> </a>
</div> </div>
<div> <div>
<a href="/Customer/Customer#fragment">Customer Area Customer Index</a> <a href="/Customer/HtmlGeneration_Customer#fragment">Customer Area Customer Index</a>
</div> </div>
<div> <div>
<a href="/Order/List">Href Order List</a> <a href="/Order/List">Href Order List</a>
</div> </div>
<div> <div>
<a href="/NonExistentController">Non-existent Controller</a> <a href="">Non-existent Controller</a>
</div> </div>
<div> <div>
<a href="/NonExistentController#fragment"> <a href="">
Non-existent Controller Fragment Non-existent Controller Fragment
</a> </a>
</div> </div>
<div> <div>
<a href="/Order/NonExistentAction">Non-existent Action</a> <a href="">Non-existent Action</a>
</div> </div>
<div> <div>
<a id="Id" href="http://somewhere/">Some Where</a> <a id="Id" href="http://somewhere/">Some Where</a>
</div> </div>
<div> <div>
<a href="unknown://localhost/NoControll#fragment"> <a href="">
Unknown Protocol Non-existent Controller Fragment Unknown Protocol Non-existent Controller Fragment
</a> </a>
</div> </div>
<div> <div>
<a href="/Product/Submit?area=NonExistentArea&amp;id=1#fragment">Product Route Non-existent Area Parameter</a> <a href="">Product Route Non-existent Area Parameter</a>
</div> </div>
<div> <div>
<a href="">Non-existent Area</a> <a href="">Non-existent Area</a>

View File

@ -0,0 +1,73 @@
<html>
<body>
<div>
<a title="&lt;the title>" href="/HtmlGeneration_Product">Product Index</a>
</div>
<div>
<a title='"the" title' href="/HtmlGeneration_Product/List">Product List</a>
</div>
<div>
<a id="HtmlGenerationWebSite_Index">HtmlGenerationWebSite Index</a>
</div>
<div>
<a href="/">Default Controller</a>
</div>
<div>
<a href="/HtmlGeneration_Product#fragment">Product Index Fragment</a>
</div>
<div>
<a href="/HtmlGeneration_Product/Submit#fragment">Product Submit Fragment</a>
</div>
<div>
<a id="HtmlGenerationWebSite_IndexFragment" href="/#fragment">
HtmlGenerationWebSite Index Fragment
</a>
</div>
<div>
<a href="ftp://localhost/#fragment">
FTP HtmlGenerationWebSite Index Fragment
</a>
</div>
<div>
<a href="unkonwn://localhost/HtmlGeneration_Product/List">
Unknown Protocol Product List
</a>
</div>
<div>
<a id="HtmlGenerationWebSite_IndexProtocol" href="/">
Empty Protocol HtmlGenerationWebSite Index
</a>
</div>
<div>
<a href="/Customer/HtmlGeneration_Customer#fragment">Customer Area Customer Index</a>
</div>
<div>
<a href="/Order/List">Href Order List</a>
</div>
<div>
<a href="/NonExistentController">Non-existent Controller</a>
</div>
<div>
<a href="/NonExistentController#fragment">
Non-existent Controller Fragment
</a>
</div>
<div>
<a href="/Order/NonExistentAction">Non-existent Action</a>
</div>
<div>
<a id="Id" href="http://somewhere/">Some Where</a>
</div>
<div>
<a href="unknown://localhost/NoControll#fragment">
Unknown Protocol Non-existent Controller Fragment
</a>
</div>
<div>
<a href="/Product/Submit?area=NonExistentArea&amp;id=1#fragment">Product Route Non-existent Area Parameter</a>
</div>
<div>
<a href="">Non-existent Area</a>
</div>
</body>
</html>

View File

@ -12,8 +12,8 @@
<body> <body>
<h1 style="font-family: cursive;">ASP.NET vNext - About</h1> <h1 style="font-family: cursive;">ASP.NET vNext - About</h1>
<p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a> <p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a>
| <a href="/home/about" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a> | <a href="/Home/About" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a>
| <a href="/home/help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p> | <a href="/Home/Help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p>
<div> <div>

View File

@ -12,8 +12,8 @@
<body> <body>
<h1 style="font-family: cursive;">ASP.NET vNext - Help</h1> <h1 style="font-family: cursive;">ASP.NET vNext - Help</h1>
<p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a> <p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a>
| <a href="/home/about" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a> | <a href="/Home/About" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a>
| <a href="/home/help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p> | <a href="/Home/Help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p>
<div> <div>

View File

@ -19,8 +19,8 @@
<body> <body>
<h1 style="font-family: cursive;">ASP.NET vNext - Home Page</h1> <h1 style="font-family: cursive;">ASP.NET vNext - Home Page</h1>
<p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a> <p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a>
| <a href="/home/about" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a> | <a href="/Home/About" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a>
| <a href="/home/help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p> | <a href="/Home/Help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p>
<div> <div>

View File

@ -12,8 +12,8 @@
<body> <body>
<h1 style="font-family: cursive;">ASP.NET vNext - </h1> <h1 style="font-family: cursive;">ASP.NET vNext - </h1>
<p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a> <p>| <a href="/" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Home</a>
| <a href="/home/about" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a> | <a href="/Home/About" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My About</a>
| <a href="/home/help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p> | <a href="/Home/Help" style="background-color: gray;color: white;border-radius: 3px;border: 1px solid black;padding: 3px;font-family: cursive;">My Help</a> |</p>
<div> <div>
<div>Items: </div> <div>Items: </div>

View File

@ -9,20 +9,22 @@ namespace ApiExplorerWebSite
{ {
public class ActionDescriptorChangeProvider : IActionDescriptorChangeProvider public class ActionDescriptorChangeProvider : IActionDescriptorChangeProvider
{ {
private ActionDescriptorChangeProvider() public ActionDescriptorChangeProvider(WellKnownChangeToken changeToken)
{ {
ChangeToken = changeToken;
} }
public static ActionDescriptorChangeProvider Instance { get; } = new ActionDescriptorChangeProvider(); public WellKnownChangeToken ChangeToken { get; }
public CancellationTokenSource TokenSource { get; private set; }
public bool HasChanged { get; set; }
public IChangeToken GetChangeToken() public IChangeToken GetChangeToken()
{ {
TokenSource = new CancellationTokenSource(); if (ChangeToken.TokenSource.IsCancellationRequested)
return new CancellationChangeToken(TokenSource.Token); {
var changeTokenSource = new CancellationTokenSource();
return new CancellationChangeToken(changeTokenSource.Token);
}
return new CancellationChangeToken(ChangeToken.TokenSource.Token);
} }
} }
} }

View File

@ -0,0 +1,35 @@
// 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.Linq;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace ApiExplorerWebSite
{
public class ApiExplorerRouteChangeConvention : Attribute, IActionModelConvention
{
public ApiExplorerRouteChangeConvention(WellKnownChangeToken changeToken)
{
ChangeToken = changeToken;
}
public WellKnownChangeToken ChangeToken { get; }
public void Apply(ActionModel action)
{
if (action.Attributes.OfType<ReloadAttribute>().Any() && ChangeToken.TokenSource.IsCancellationRequested)
{
action.ActionName = "NewIndex";
action.Selectors.Clear();
action.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Template = "NewIndex"
}
});
}
}
}
}

View File

@ -1,45 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace ApiExplorerWebSite namespace ApiExplorerWebSite
{ {
[Route("ApiExplorerReload")] [Route("ApiExplorerReload")]
public class ApiExplorerReloadableController : Controller public class ApiExplorerReloadableController : Controller
{ {
[ApiExplorerRouteChangeConvention]
[Route("Index")] [Route("Index")]
[Reload]
public string Index() => "Hello world"; public string Index() => "Hello world";
[Route("Reload")] [Route("Reload")]
[PassThru] [PassThru]
public IActionResult Reload() public IActionResult Reload([FromServices] WellKnownChangeToken changeToken)
{ {
ActionDescriptorChangeProvider.Instance.HasChanged = true; changeToken.TokenSource.Cancel();
ActionDescriptorChangeProvider.Instance.TokenSource.Cancel();
return Ok(); return Ok();
} }
public class ApiExplorerRouteChangeConventionAttribute : Attribute, IActionModelConvention
{
public void Apply(ActionModel action)
{
if (ActionDescriptorChangeProvider.Instance.HasChanged)
{
action.ActionName = "NewIndex";
action.Selectors.Clear();
action.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Template = "NewIndex"
}
});
}
}
}
} }
} }

View File

@ -0,0 +1,8 @@
using System;
namespace ApiExplorerWebSite
{
public class ReloadAttribute : Attribute
{
}
}

View File

@ -6,6 +6,7 @@ using System.Linq;
using ApiExplorerWebSite.Controllers; using ApiExplorerWebSite.Controllers;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -19,6 +20,8 @@ namespace ApiExplorerWebSite
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddTransient<ILoggerFactory, LoggerFactory>(); services.AddTransient<ILoggerFactory, LoggerFactory>();
var wellKnownChangeToken = new WellKnownChangeToken();
services.AddMvc(options => services.AddMvc(options =>
{ {
options.Filters.AddService(typeof(ApiExplorerDataFilter)); options.Filters.AddService(typeof(ApiExplorerDataFilter));
@ -28,17 +31,19 @@ namespace ApiExplorerWebSite
typeof(ApiExplorerVisbilityDisabledByConventionController))); typeof(ApiExplorerVisbilityDisabledByConventionController)));
options.Conventions.Add(new ApiExplorerInboundOutboundConvention( options.Conventions.Add(new ApiExplorerInboundOutboundConvention(
typeof(ApiExplorerInboundOutBoundController))); typeof(ApiExplorerInboundOutBoundController)));
options.Conventions.Add(new ApiExplorerRouteChangeConvention(wellKnownChangeToken));
var jsonOutputFormatter = options.OutputFormatters.OfType<JsonOutputFormatter>().First(); var jsonOutputFormatter = options.OutputFormatters.OfType<JsonOutputFormatter>().First();
options.OutputFormatters.Clear(); options.OutputFormatters.Clear();
options.OutputFormatters.Add(jsonOutputFormatter); options.OutputFormatters.Add(jsonOutputFormatter);
options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter()); options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
}); })
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddSingleton<ApiExplorerDataFilter>(); services.AddSingleton<ApiExplorerDataFilter>();
services.AddSingleton<IActionDescriptorChangeProvider>(ActionDescriptorChangeProvider.Instance); services.AddSingleton<IActionDescriptorChangeProvider, ActionDescriptorChangeProvider>();
services.AddSingleton(ActionDescriptorChangeProvider.Instance); services.AddSingleton(wellKnownChangeToken);
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)

View File

@ -0,0 +1,12 @@
// 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.Threading;
namespace ApiExplorerWebSite
{
public class WellKnownChangeToken
{
public CancellationTokenSource TokenSource { get; } = new CancellationTokenSource();
}
}

View File

@ -4,6 +4,7 @@
using System.IO; using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace ApplicationModelWebSite namespace ApplicationModelWebSite
@ -20,7 +21,8 @@ namespace ApplicationModelWebSite
options.Conventions.Add(new FromHeaderConvention()); options.Conventions.Add(new FromHeaderConvention());
options.Conventions.Add(new MultipleAreasControllerConvention()); options.Conventions.Add(new MultipleAreasControllerConvention());
options.Conventions.Add(new CloneActionConvention()); options.Conventions.Add(new CloneActionConvention());
}); })
.SetCompatibilityVersion(CompatibilityVersion.Latest);
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)

View File

@ -5,6 +5,7 @@ using System;
using System.IO; using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace BasicWebSite namespace BasicWebSite
@ -13,7 +14,8 @@ namespace BasicWebSite
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.ConfigureBaseWebSiteAuthPolicies(); services.ConfigureBaseWebSiteAuthPolicies();
} }

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace BasicWebSite namespace BasicWebSite
@ -10,7 +11,8 @@ namespace BasicWebSite
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.Configure<CookiePolicyOptions>(o => services.Configure<CookiePolicyOptions>(o =>
{ {

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace BasicWebSite namespace BasicWebSite
@ -13,7 +14,8 @@ namespace BasicWebSite
// CookieTempDataProvider is the default ITempDataProvider, so we must override it with session. // CookieTempDataProvider is the default ITempDataProvider, so we must override it with session.
services services
.AddMvc() .AddMvc()
.AddSessionStateTempDataProvider(); .AddSessionStateTempDataProvider()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddSession(); services.AddSession();
services.ConfigureBaseWebSiteAuthPolicies(); services.ConfigureBaseWebSiteAuthPolicies();

View File

@ -11,7 +11,7 @@ using ControllersFromServicesWebSite.Components;
using ControllersFromServicesWebSite.TagHelpers; using ControllersFromServicesWebSite.TagHelpers;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -36,7 +36,8 @@ namespace ControllersFromServicesWebSite
}) })
.AddControllersAsServices() .AddControllersAsServices()
.AddViewComponentsAsServices() .AddViewComponentsAsServices()
.AddTagHelpersAsServices(); .AddTagHelpersAsServices()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddTransient<QueryValueService>(); services.AddTransient<QueryValueService>();
services.AddTransient<ValueService>(); services.AddTransient<ValueService>();

View File

@ -1,10 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace CorsWebSite namespace CorsWebSite
@ -13,7 +12,8 @@ namespace CorsWebSite
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.Configure<CorsOptions>(options => services.Configure<CorsOptions>(options =>
{ {
options.AddPolicy( options.AddPolicy(

View File

@ -1,19 +1,19 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace CorsWebSite namespace CorsWebSite
{ {
public class StartupWithEndpointRouting public class StartupWith21Compat
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc(options => options.EnableEndpointRouting = true); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.Configure<CorsOptions>(options => services.Configure<CorsOptions>(options =>
{ {
options.AddPolicy( options.AddPolicy(

View File

@ -4,6 +4,7 @@
using System.IO; using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace ErrorPageMiddlewareWebSite namespace ErrorPageMiddlewareWebSite
@ -13,7 +14,8 @@ namespace ErrorPageMiddlewareWebSite
// Set up application services // Set up application services
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)

View File

@ -4,6 +4,7 @@
using System.IO; using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace FilesWebSite namespace FilesWebSite
@ -13,7 +14,8 @@ namespace FilesWebSite
// Set up application services // Set up application services
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)

View File

@ -4,6 +4,7 @@
using System.IO; using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.TagHelpers; using Microsoft.AspNetCore.Mvc.TagHelpers;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -16,7 +17,9 @@ namespace HtmlGenerationWebSite
{ {
// Add MVC services to the services container. Change default FormTagHelper.AntiForgery to false. Usually // Add MVC services to the services container. Change default FormTagHelper.AntiForgery to false. Usually
// null which is interpreted as true unless element includes an action attribute. // null which is interpreted as true unless element includes an action attribute.
services.AddMvc().InitializeTagHelper<FormTagHelper>((helper, _) => helper.Antiforgery = false); services.AddMvc()
.InitializeTagHelper<FormTagHelper>((helper, _) => helper.Antiforgery = false)
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddSingleton(typeof(ISignalTokenProviderService<>), typeof(SignalTokenProviderService<>)); services.AddSingleton(typeof(ISignalTokenProviderService<>), typeof(SignalTokenProviderService<>));
services.AddSingleton<ProductsService>(); services.AddSingleton<ProductsService>();

View File

@ -0,0 +1,55 @@
// 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.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.TagHelpers;
using Microsoft.Extensions.DependencyInjection;
namespace HtmlGenerationWebSite
{
public class StartupWith21CompatibilityBehavior
{
// Set up application services
public void ConfigureServices(IServiceCollection services)
{
// Add MVC services to the services container. Change default FormTagHelper.AntiForgery to false. Usually
// null which is interpreted as true unless element includes an action attribute.
services.AddMvc()
.InitializeTagHelper<FormTagHelper>((helper, _) => helper.Antiforgery = false)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton(typeof(ISignalTokenProviderService<>), typeof(SignalTokenProviderService<>));
services.AddSingleton<ProductsService>();
}
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller}/{action}/{id?}",
defaults: new { action = "Index" });
routes.MapRoute(
name: "productRoute",
template: "Product/{action}",
defaults: new { controller = "Product" });
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "HtmlGeneration_Home", action = "Index" });
});
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
new WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseKestrel()
.UseIISIntegration();
}
}

View File

@ -5,7 +5,6 @@ using System.Globalization;
using System.IO; using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace HtmlGenerationWebSite namespace HtmlGenerationWebSite

View File

@ -19,7 +19,7 @@
<a asp-action="Index">Default Controller</a> <a asp-action="Index">Default Controller</a>
</div> </div>
<div> <div>
<a asp-fragment="fragment" asp-controller="Product">Product Index Fragment</a> <a asp-fragment="fragment" asp-controller="HtmlGeneration_Product">Product Index Fragment</a>
</div> </div>
<div> <div>
<a asp-controller="HtmlGeneration_Product" asp-action="Submit" asp-fragment="fragment">Product Submit Fragment</a> <a asp-controller="HtmlGeneration_Product" asp-action="Submit" asp-fragment="fragment">Product Submit Fragment</a>
@ -46,7 +46,7 @@
</div> </div>
<div> <div>
<a asp-route="areaRoute" asp-route-area="Customer" <a asp-route="areaRoute" asp-route-area="Customer"
asp-route-controller="Customer" asp-route-controller="HtmlGeneration_Customer"
asp-route-action="Index" asp-route-action="Index"
asp-fragment="fragment">Customer Area Customer Index</a> asp-fragment="fragment">Customer Area Customer Index</a>
</div> </div>

View File

@ -4,6 +4,7 @@
using System.IO; using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace RazorBuildWebSite namespace RazorBuildWebSite
@ -12,7 +13,8 @@ namespace RazorBuildWebSite
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)

View File

@ -4,6 +4,7 @@
using System.Globalization; using System.Globalization;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using RazorPagesWebSite.Conventions; using RazorPagesWebSite.Conventions;
@ -25,7 +26,8 @@ namespace RazorPagesWebSite
options.Conventions.AddPageRoute("/Pages/NotTheRoot", string.Empty); options.Conventions.AddPageRoute("/Pages/NotTheRoot", string.Empty);
options.Conventions.Add(new CustomModelTypeConvention()); options.Conventions.Add(new CustomModelTypeConvention());
}) })
.WithRazorPagesAtContentRoot(); .WithRazorPagesAtContentRoot()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)

View File

@ -3,6 +3,7 @@
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using RazorPagesWebSite.Conventions; using RazorPagesWebSite.Conventions;
@ -24,7 +25,8 @@ namespace RazorPagesWebSite
options.Conventions.AuthorizeAreaFolder("Accounts", "/RequiresAuth"); options.Conventions.AuthorizeAreaFolder("Accounts", "/RequiresAuth");
options.Conventions.AllowAnonymousToAreaPage("Accounts", "/RequiresAuth/AllowAnonymous"); options.Conventions.AllowAnonymousToAreaPage("Accounts", "/RequiresAuth/AllowAnonymous");
options.Conventions.Add(new CustomModelTypeConvention()); options.Conventions.Add(new CustomModelTypeConvention());
}); })
.SetCompatibilityVersion(CompatibilityVersion.Latest);
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)

View File

@ -7,6 +7,8 @@ namespace RazorWebSite.Controllers
{ {
public class EmbeddedViewsController : Controller public class EmbeddedViewsController : Controller
{ {
public IActionResult Index() => null;
public IActionResult LookupByName() => View("Index"); public IActionResult LookupByName() => View("Index");
public IActionResult LookupByPath() => View("/Views/EmbeddedViews/Index.cshtml"); public IActionResult LookupByPath() => View("/Views/EmbeddedViews/Index.cshtml");

View File

@ -6,6 +6,7 @@ using System.Globalization;
using System.Reflection; using System.Reflection;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -41,7 +42,8 @@ namespace RazorWebSite
options.HtmlHelperOptions.ValidationMessageElement = "validationMessageElement"; options.HtmlHelperOptions.ValidationMessageElement = "validationMessageElement";
options.HtmlHelperOptions.ValidationSummaryMessageElement = "validationSummaryElement"; options.HtmlHelperOptions.ValidationSummaryMessageElement = "validationSummaryElement";
}) })
.AddMvcLocalization(LanguageViewLocationExpanderFormat.SubFolder); .AddMvcLocalization(LanguageViewLocationExpanderFormat.SubFolder)
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddTransient<InjectedHelper>(); services.AddTransient<InjectedHelper>();
services.AddTransient<TaskReturningService>(); services.AddTransient<TaskReturningService>();

View File

@ -6,7 +6,6 @@ using System.Globalization;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace RazorWebSite namespace RazorWebSite
@ -25,8 +24,8 @@ namespace RazorWebSite
{ {
options.DataAnnotationLocalizerProvider = options.DataAnnotationLocalizerProvider =
(modelType, stringLocalizerFactory) => stringLocalizerFactory.Create(typeof(SingleType)); (modelType, stringLocalizerFactory) => stringLocalizerFactory.Create(typeof(SingleType));
}); })
services.Configure<MvcCompatibilityOptions>(options => options.CompatibilityVersion = CompatibilityVersion.Latest); .SetCompatibilityVersion(CompatibilityVersion.Latest);
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

View File

@ -1,9 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -14,7 +13,8 @@ namespace RoutingWebSite
// Set up application services // Set up application services
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddScoped<TestResponseGenerator>(); services.AddScoped<TestResponseGenerator>();
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
@ -29,8 +29,7 @@ namespace RoutingWebSite
"adminRoute", "adminRoute",
"{area:exists}/{controller}/{action}", "{area:exists}/{controller}/{action}",
new { controller = "Home", action = "Index" }, new { controller = "Home", action = "Index" },
new { area = "Travel" } new { area = "Travel" });
);
routes.MapRoute( routes.MapRoute(
"ActionAsMethod", "ActionAsMethod",
@ -43,5 +42,4 @@ namespace RoutingWebSite
}); });
} }
} }
} }

View File

@ -2,18 +2,19 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace RoutingWebSite namespace RoutingWebSite
{ {
public class StartupWithEndpointRouting public class StartupWith21Compat
{ {
// Set up application services // Set up application services
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc() services.AddMvc()
.AddMvcOptions(options => options.EnableEndpointRouting = true); .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddScoped<TestResponseGenerator>(); services.AddScoped<TestResponseGenerator>();
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

View File

@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization.Policy; using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace SecurityWebSite namespace SecurityWebSite
@ -14,7 +15,8 @@ namespace SecurityWebSite
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
// Add framework services. // Add framework services.
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddAntiforgery(); services.AddAntiforgery();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options => services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{ {

View File

@ -0,0 +1,41 @@
// 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.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.DependencyInjection;
namespace SecurityWebSite
{
public class StartupWith20CompatAndGlobalDenyAnonymousFilter
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Home/Login";
options.LogoutPath = "/Home/Logout";
}).AddCookie("Cookie2");
services.AddMvc(o =>
{
o.Filters.Add(new AuthorizeFilter());
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_0);
services.AddScoped<IPolicyEvaluator, CountingPolicyEvaluator>();
}
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
}
}

View File

@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization.Policy; using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -24,7 +25,8 @@ namespace SecurityWebSite
services.AddMvc(o => services.AddMvc(o =>
{ {
o.Filters.Add(new AuthorizeFilter()); o.Filters.Add(new AuthorizeFilter());
}); })
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddScoped<IPolicyEvaluator, CountingPolicyEvaluator>(); services.AddScoped<IPolicyEvaluator, CountingPolicyEvaluator>();
} }

View File

@ -2,11 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO; using System.IO;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.WebEncoders.Testing;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -21,7 +20,8 @@ namespace SimpleWebSite
.AddMvcCore() .AddMvcCore()
.AddAuthorization() .AddAuthorization()
.AddFormatterMappings(m => m.SetMediaTypeMappingForFormat("js", new MediaTypeHeaderValue("application/json"))) .AddFormatterMappings(m => m.SetMediaTypeMappingForFormat("js", new MediaTypeHeaderValue("application/json")))
.AddJsonFormatters(j => j.Formatting = Formatting.Indented); .AddJsonFormatters(j => j.Formatting = Formatting.Indented)
.SetCompatibilityVersion(CompatibilityVersion.Latest);
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)

View File

@ -4,6 +4,7 @@
using System.IO; using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace TagHelpersWebSite namespace TagHelpersWebSite
@ -13,7 +14,8 @@ namespace TagHelpersWebSite
// Set up application services // Set up application services
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)

View File

@ -1,9 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -14,7 +13,8 @@ namespace VersioningWebSite
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
// Add MVC services to the services container // Add MVC services to the services container
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddScoped<TestResponseGenerator>(); services.AddScoped<TestResponseGenerator>();
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

View File

@ -1,21 +1,20 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace VersioningWebSite namespace VersioningWebSite
{ {
public class StartupWithEndpointRouting public class StartupWith21Compat
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
// Add MVC services to the services container // Add MVC services to the services container
services.AddMvc() services.AddMvc()
.AddMvcOptions(options => options.EnableEndpointRouting = true); .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddScoped<TestResponseGenerator>(); services.AddScoped<TestResponseGenerator>();
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

View File

@ -4,6 +4,7 @@
using System.IO; using System.IO;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace WebApiCompatShimWebSite namespace WebApiCompatShimWebSite
@ -13,7 +14,10 @@ namespace WebApiCompatShimWebSite
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
// Add MVC services to the services container // Add MVC services to the services container
services.AddMvc().AddWebApiConventions(); services.AddMvc()
.AddWebApiConventions()
.SetCompatibilityVersion(CompatibilityVersion.Latest)
.AddMvcOptions(options => options.EnableEndpointRouting = false);
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)

View File

@ -17,7 +17,8 @@ namespace XmlFormattersWebSite
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
// Add MVC services to the services container // Add MVC services to the services container
services.AddMvc(); services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
services.Configure<MvcOptions>(options => services.Configure<MvcOptions>(options =>
{ {