| File: Routing\MvcAttributeRouteHandler.cs | Web Access |
| Project: src\aspnetcore\src\Mvc\Mvc.Core\src\Microsoft.AspNetCore.Mvc.Core.csproj (Microsoft.AspNetCore.Mvc.Core) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Resources = Microsoft.AspNetCore.Mvc.Core.Resources; namespace Microsoft.AspNetCore.Mvc.Routing; internal sealed class MvcAttributeRouteHandler : IRouter { private readonly IActionInvokerFactory _actionInvokerFactory; private readonly IActionSelector _actionSelector; private readonly ILogger _logger; private readonly DiagnosticListener _diagnosticListener; public MvcAttributeRouteHandler( IActionInvokerFactory actionInvokerFactory, IActionSelector actionSelector, DiagnosticListener diagnosticListener, ILoggerFactory loggerFactory) { _actionInvokerFactory = actionInvokerFactory; _actionSelector = actionSelector; _diagnosticListener = diagnosticListener; _logger = loggerFactory.CreateLogger(typeof(MvcAttributeRouteHandler)); } public ActionDescriptor[]? Actions { get; set; } public VirtualPathData? GetVirtualPath(VirtualPathContext context) { ArgumentNullException.ThrowIfNull(context); // We return null here because we're not responsible for generating the url, the route is. return null; } public Task RouteAsync(RouteContext context) { ArgumentNullException.ThrowIfNull(context); if (Actions == null) { var message = Resources.FormatPropertyOfTypeCannotBeNull( nameof(Actions), nameof(MvcAttributeRouteHandler)); throw new InvalidOperationException(message); } var actionDescriptor = _actionSelector.SelectBestCandidate(context, Actions); if (actionDescriptor == null) { _logger.NoActionsMatched(context.RouteData.Values); return Task.CompletedTask; } foreach (var kvp in actionDescriptor.RouteValues) { if (!string.IsNullOrEmpty(kvp.Value)) { context.RouteData.Values[kvp.Key] = kvp.Value; } } context.Handler = (c) => { var routeData = c.GetRouteData(); var actionContext = new ActionContext(context.HttpContext, routeData, actionDescriptor); var invoker = _actionInvokerFactory.CreateInvoker(actionContext); if (invoker == null) { throw new InvalidOperationException( Resources.FormatActionInvokerFactory_CouldNotCreateInvoker( actionDescriptor.DisplayName)); } return invoker.InvokeAsync(); }; return Task.CompletedTask; } }