Merge remote-tracking branch 'origin/release/2.2'

This commit is contained in:
Ryan Nowak 2018-07-23 08:06:47 -07:00
commit 3c1034cf12
14 changed files with 52 additions and 76 deletions

View File

@ -261,7 +261,7 @@ namespace Microsoft.Extensions.DependencyInjection
services.TryAddTransient<MvcAttributeRouteHandler>(); // Many per app services.TryAddTransient<MvcAttributeRouteHandler>(); // Many per app
// //
// Dispatching // Global Routing / Endpoints
// //
services.TryAddEnumerable( services.TryAddEnumerable(
ServiceDescriptor.Singleton<EndpointDataSource, MvcEndpointDataSource>()); ServiceDescriptor.Singleton<EndpointDataSource, MvcEndpointDataSource>());

View File

@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
// up the endpoints too. // up the endpoints too.
// //
// Start with an order of '1' for conventional routes as attribute routes have a default order of '0'. // Start with an order of '1' for conventional routes as attribute routes have a default order of '0'.
// This is for scenarios dealing with migrating existing Routing based code to Dispatcher world. // This is for scenarios dealing with migrating existing Router based code to Global Routing world.
var conventionalRouteOrder = 0; var conventionalRouteOrder = 0;
// Check each of the conventional templates to see if the action would be reachable // Check each of the conventional templates to see if the action would be reachable

View File

@ -12,14 +12,14 @@ namespace Microsoft.AspNetCore.Mvc.Routing
/// An implementation of <see cref="IUrlHelper"/> that uses <see cref="LinkGenerator"/> to build URLs /// An implementation of <see cref="IUrlHelper"/> that uses <see cref="LinkGenerator"/> to build URLs
/// for ASP.NET MVC within an application. /// for ASP.NET MVC within an application.
/// </summary> /// </summary>
internal class DispatcherUrlHelper : UrlHelperBase internal class GlobalRoutingUrlHelper : UrlHelperBase
{ {
private readonly ILogger<DispatcherUrlHelper> _logger; private readonly ILogger<GlobalRoutingUrlHelper> _logger;
private readonly LinkGenerator _linkGenerator; private readonly LinkGenerator _linkGenerator;
private readonly IEndpointFinder<RouteValuesBasedEndpointFinderContext> _routeValuesBasedEndpointFinder; private readonly IEndpointFinder<RouteValuesBasedEndpointFinderContext> _routeValuesBasedEndpointFinder;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DispatcherUrlHelper"/> class using the specified /// Initializes a new instance of the <see cref="GlobalRoutingUrlHelper"/> class using the specified
/// <paramref name="actionContext"/>. /// <paramref name="actionContext"/>.
/// </summary> /// </summary>
/// <param name="actionContext">The <see cref="Mvc.ActionContext"/> for the current request.</param> /// <param name="actionContext">The <see cref="Mvc.ActionContext"/> for the current request.</param>
@ -28,11 +28,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
/// </param> /// </param>
/// <param name="linkGenerator">The <see cref="LinkGenerator"/> used to generate the link.</param> /// <param name="linkGenerator">The <see cref="LinkGenerator"/> used to generate the link.</param>
/// <param name="logger">The <see cref="ILogger"/>.</param> /// <param name="logger">The <see cref="ILogger"/>.</param>
public DispatcherUrlHelper( public GlobalRoutingUrlHelper(
ActionContext actionContext, ActionContext actionContext,
IEndpointFinder<RouteValuesBasedEndpointFinderContext> routeValuesBasedEndpointFinder, IEndpointFinder<RouteValuesBasedEndpointFinderContext> routeValuesBasedEndpointFinder,
LinkGenerator linkGenerator, LinkGenerator linkGenerator,
ILogger<DispatcherUrlHelper> logger) ILogger<GlobalRoutingUrlHelper> logger)
: base(actionContext) : base(actionContext)
{ {
if (linkGenerator == null) if (linkGenerator == null)

View File

@ -53,9 +53,9 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var services = httpContext.RequestServices; var services = httpContext.RequestServices;
var linkGenerator = services.GetRequiredService<LinkGenerator>(); var linkGenerator = services.GetRequiredService<LinkGenerator>();
var routeValuesBasedEndpointFinder = services.GetRequiredService<IEndpointFinder<RouteValuesBasedEndpointFinderContext>>(); var routeValuesBasedEndpointFinder = services.GetRequiredService<IEndpointFinder<RouteValuesBasedEndpointFinderContext>>();
var logger = services.GetRequiredService<ILogger<DispatcherUrlHelper>>(); var logger = services.GetRequiredService<ILogger<GlobalRoutingUrlHelper>>();
urlHelper = new DispatcherUrlHelper( urlHelper = new GlobalRoutingUrlHelper(
context, context,
routeValuesBasedEndpointFinder, routeValuesBasedEndpointFinder,
linkGenerator, linkGenerator,

View File

@ -71,11 +71,24 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
}; };
} }
string message = null;
if (!output.IsContentModified)
{
var tagHelperContent = await output.GetChildContentAsync();
// We check for whitespace to detect scenarios such as:
// <span validation-for="Name">
// </span>
if (!tagHelperContent.IsEmptyOrWhiteSpace)
{
message = tagHelperContent.GetContent();
}
}
var tagBuilder = Generator.GenerateValidationMessage( var tagBuilder = Generator.GenerateValidationMessage(
ViewContext, ViewContext,
For.ModelExplorer, For.ModelExplorer,
For.Name, For.Name,
message: null, message: message,
tag: null, tag: null,
htmlAttributes: htmlAttributes); htmlAttributes: htmlAttributes);
@ -84,27 +97,12 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
output.MergeAttributes(tagBuilder); output.MergeAttributes(tagBuilder);
// Do not update the content if another tag helper targeting this element has already done so. // Do not update the content if another tag helper targeting this element has already done so.
if (!output.IsContentModified) if (!output.IsContentModified && tagBuilder.HasInnerHtml)
{ {
// We check for whitespace to detect scenarios such as: output.Content.SetHtmlContent(tagBuilder.InnerHtml);
// <span validation-for="Name">
// </span>
var childContent = await output.GetChildContentAsync();
if (childContent.IsEmptyOrWhiteSpace)
{
// Provide default message text (if any) since there was nothing useful in the Razor source.
if (tagBuilder.HasInnerHtml)
{
output.Content.SetHtmlContent(tagBuilder.InnerHtml);
}
}
else
{
output.Content.SetHtmlContent(childContent);
}
} }
} }
} }
} }
} }
} }

View File

@ -14,7 +14,7 @@ using Xunit;
namespace Microsoft.AspNetCore.Mvc.Routing namespace Microsoft.AspNetCore.Mvc.Routing
{ {
public class DispatcherUrlHelperTest : UrlHelperTestBase public class GlobalRoutingUrlHelperTest : UrlHelperTestBase
{ {
protected override IUrlHelper CreateUrlHelper(string appRoot, string host, string protocol) protected override IUrlHelper CreateUrlHelper(string appRoot, string host, string protocol)
{ {
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var urlHelperFactory = httpContext.RequestServices.GetRequiredService<IUrlHelperFactory>(); var urlHelperFactory = httpContext.RequestServices.GetRequiredService<IUrlHelperFactory>();
var urlHelper = urlHelperFactory.GetUrlHelper(actionContext); var urlHelper = urlHelperFactory.GetUrlHelper(actionContext);
Assert.IsType<DispatcherUrlHelper>(urlHelper); Assert.IsType<GlobalRoutingUrlHelper>(urlHelper);
return urlHelper; return urlHelper;
} }
@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
} }
var services = GetCommonServices(); var services = GetCommonServices();
services.AddDispatcher(); services.AddRouting();
services.TryAddEnumerable( services.TryAddEnumerable(
ServiceDescriptor.Singleton<EndpointDataSource>(new DefaultEndpointDataSource(endpoints))); ServiceDescriptor.Singleton<EndpointDataSource>(new DefaultEndpointDataSource(endpoints)));
services.TryAddSingleton<IUrlHelperFactory, UrlHelperFactory>(); services.TryAddSingleton<IUrlHelperFactory, UrlHelperFactory>();

View File

@ -3,9 +3,9 @@
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class ConsumesAttributeDispatchingTests : ConsumesAttributeTestsBase<BasicWebSite.StartupWithDispatching> public class ConsumesAttributeGlobalRoutingTests : ConsumesAttributeTestsBase<BasicWebSite.StartupWithGlobalRouting>
{ {
public ConsumesAttributeDispatchingTests(MvcTestFixture<BasicWebSite.StartupWithDispatching> fixture) public ConsumesAttributeGlobalRoutingTests(MvcTestFixture<BasicWebSite.StartupWithGlobalRouting> fixture)
: base(fixture) : base(fixture)
{ {
} }

View File

@ -4,39 +4,25 @@
using System; using System;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Routing;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class DispatchingTests : RoutingTestsBase<RoutingWebSite.StartupWithDispatching> public class GlobalRoutingTest : RoutingTestsBase<RoutingWebSite.StartupWithGlobalRouting>
{ {
public DispatchingTests(MvcTestFixture<RoutingWebSite.StartupWithDispatching> fixture) public GlobalRoutingTest(MvcTestFixture<RoutingWebSite.StartupWithGlobalRouting> fixture)
: base(fixture) : base(fixture)
{ {
} }
[Fact(Skip = "Link generation issue in dispatching. Need to fix - https://github.com/aspnet/Routing/issues/590")] [Fact(Skip = "Link generation issue in global routing. Need to fix - https://github.com/aspnet/Routing/issues/590")]
public override Task AttributeRoutedAction_InArea_ExplicitLeaveArea()
{
return Task.CompletedTask;
}
[Fact(Skip = "Link generation issue in dispatching. Need to fix - https://github.com/aspnet/Routing/issues/590")]
public override Task AttributeRoutedAction_InArea_StaysInArea_ActionDoesntExist() public override Task AttributeRoutedAction_InArea_StaysInArea_ActionDoesntExist()
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
[Fact(Skip = "Link generation issue in dispatching. Need to fix - https://github.com/aspnet/Routing/issues/590")] [Fact(Skip = "Link generation issue in global routing. Need to fix - https://github.com/aspnet/Routing/issues/590")]
public override Task ConventionalRoutedAction_InArea_ExplicitLeaveArea()
{
return Task.CompletedTask;
}
[Fact(Skip = "Link generation issue in dispatching. Need to fix - https://github.com/aspnet/Routing/issues/590")]
public override Task ConventionalRoutedAction_InArea_StaysInArea() public override Task ConventionalRoutedAction_InArea_StaysInArea()
{ {
return Task.CompletedTask; return Task.CompletedTask;

View File

@ -3,9 +3,9 @@
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class VersioningDispatchingTests : VersioningTestsBase<VersioningWebSite.StartupWithDispatching> public class RequestServicesGlobalRoutingTest : RequestServicesTestBase<BasicWebSite.StartupWithGlobalRouting>
{ {
public VersioningDispatchingTests(MvcTestFixture<VersioningWebSite.StartupWithDispatching> fixture) public RequestServicesGlobalRoutingTest(MvcTestFixture<BasicWebSite.StartupWithGlobalRouting> fixture)
: base(fixture) : base(fixture)
{ {
} }

View File

@ -3,9 +3,9 @@
namespace Microsoft.AspNetCore.Mvc.FunctionalTests namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{ {
public class RequestServicesDispatchingTest : RequestServicesTestBase<BasicWebSite.StartupWithDispatching> public class VersioningGlobalRoutingTests : VersioningTestsBase<VersioningWebSite.StartupWithGlobalRouting>
{ {
public RequestServicesDispatchingTest(MvcTestFixture<BasicWebSite.StartupWithDispatching> fixture) public VersioningGlobalRoutingTests(MvcTestFixture<VersioningWebSite.StartupWithGlobalRouting> fixture)
: base(fixture) : base(fixture)
{ {
} }

View File

@ -357,10 +357,11 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
} }
[Theory] [Theory]
[InlineData("Content of validation message", "Content of validation message")] [InlineData("Content of validation message", "Content of validation message", "New HTML")]
[InlineData("\r\n \r\n", "New HTML")] [InlineData("\r\n \r\n", null, "New HTML")]
public async Task ProcessAsync_MergesTagBuilderFromGenerateValidationMessage( public async Task ProcessAsync_MergesTagBuilderFromGenerateValidationMessage(
string childContent, string childContent,
string expectedMessage,
string expectedOutputContent) string expectedOutputContent)
{ {
// Arrange // Arrange
@ -375,7 +376,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
It.IsAny<ViewContext>(), It.IsAny<ViewContext>(),
It.IsAny<ModelExplorer>(), It.IsAny<ModelExplorer>(),
It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<string>(), expectedMessage,
It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<object>())) It.IsAny<object>()))
.Returns(tagBuilder); .Returns(tagBuilder);

View File

@ -7,12 +7,12 @@ using Microsoft.Extensions.DependencyInjection;
namespace BasicWebSite namespace BasicWebSite
{ {
public class StartupWithDispatching public class StartupWithGlobalRouting
{ {
// Set up application services // Set up application services
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddDispatcher(); services.AddRouting();
services.AddMvc() services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest) .SetCompatibilityVersion(CompatibilityVersion.Latest)
@ -29,7 +29,7 @@ namespace BasicWebSite
// Initializes the RequestId service for each request // Initializes the RequestId service for each request
app.UseMiddleware<RequestIdMiddleware>(); app.UseMiddleware<RequestIdMiddleware>();
app.UseDispatcher(); app.UseGlobalRouting();
app.UseMvcWithEndpoint(routes => app.UseMvcWithEndpoint(routes =>
{ {

View File

@ -1,27 +1,18 @@
// 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 System.IO;
using System.Text;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Matchers;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
namespace RoutingWebSite namespace RoutingWebSite
{ {
public class StartupWithDispatching public class StartupWithGlobalRouting
{ {
// Set up application services // Set up application services
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddDispatcher(); services.AddRouting();
services.AddMvc(); services.AddMvc();
@ -31,7 +22,7 @@ namespace RoutingWebSite
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)
{ {
app.UseDispatcher(); app.UseGlobalRouting();
app.UseMvcWithEndpoint(routes => app.UseMvcWithEndpoint(routes =>
{ {

View File

@ -9,11 +9,11 @@ using Microsoft.Extensions.DependencyInjection;
namespace VersioningWebSite namespace VersioningWebSite
{ {
public class StartupWithDispatching public class StartupWithGlobalRouting
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddDispatcher(); services.AddRouting();
// Add MVC services to the services container // Add MVC services to the services container
services.AddMvc(); services.AddMvc();
@ -24,7 +24,7 @@ namespace VersioningWebSite
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)
{ {
app.UseDispatcher(); app.UseGlobalRouting();
app.UseMvcWithEndpoint(endpoints => app.UseMvcWithEndpoint(endpoints =>
{ {