| File: ApplicationModels\CompiledPageActionDescriptorBuilder.cs | Web Access |
| Project: src\aspnetcore\src\Mvc\Mvc.RazorPages\src\Microsoft.AspNetCore.Mvc.RazorPages.csproj (Microsoft.AspNetCore.Mvc.RazorPages) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Linq; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure; namespace Microsoft.AspNetCore.Mvc.ApplicationModels; /// <summary> /// Constructs a <see cref="CompiledPageActionDescriptor"/> from an <see cref="PageApplicationModel"/>. /// </summary> internal static class CompiledPageActionDescriptorBuilder { /// <summary> /// Creates a <see cref="CompiledPageActionDescriptor"/> from the specified <paramref name="applicationModel"/>. /// </summary> /// <param name="applicationModel">The <see cref="PageApplicationModel"/>.</param> /// <param name="globalFilters">Global filters to apply to the page.</param> /// <returns>The <see cref="CompiledPageActionDescriptor"/>.</returns> public static CompiledPageActionDescriptor Build( PageApplicationModel applicationModel, FilterCollection globalFilters) { var boundProperties = CreateBoundProperties(applicationModel); var filters = Enumerable.Concat( globalFilters.Select(f => new FilterDescriptor(f, FilterScope.Global)), applicationModel.Filters.Select(f => new FilterDescriptor(f, FilterScope.Action))) .ToArray(); var handlerMethods = CreateHandlerMethods(applicationModel); if (applicationModel.ModelType != null && applicationModel.DeclaredModelType != null && !applicationModel.DeclaredModelType.IsAssignableFrom(applicationModel.ModelType)) { var message = Resources.FormatInvalidActionDescriptorModelType( applicationModel.ActionDescriptor.DisplayName, applicationModel.ModelType.Name, applicationModel.DeclaredModelType.Name); throw new InvalidOperationException(message); } var actionDescriptor = applicationModel.ActionDescriptor; return new CompiledPageActionDescriptor(actionDescriptor) { ActionConstraints = actionDescriptor.ActionConstraints, AttributeRouteInfo = actionDescriptor.AttributeRouteInfo, BoundProperties = boundProperties, EndpointMetadata = CreateEndPointMetadata(applicationModel), FilterDescriptors = filters, HandlerMethods = handlerMethods, HandlerTypeInfo = applicationModel.HandlerType, DeclaredModelTypeInfo = applicationModel.DeclaredModelType, ModelTypeInfo = applicationModel.ModelType, RouteValues = actionDescriptor.RouteValues, PageTypeInfo = applicationModel.PageType, Properties = applicationModel.Properties, }; } private static IList<object> CreateEndPointMetadata(PageApplicationModel applicationModel) { var handlerMetatdata = applicationModel.HandlerTypeAttributes; var endpointMetadata = applicationModel.EndpointMetadata; // It is critical to get the order in which metadata appears in endpoint metadata correct. More significant metadata // must appear later in the sequence. // In this case, handlerMetadata is attributes on the Page \ PageModel, and endPointMetadata is configured via conventions. and // We consider the latter to be more significant. return Enumerable.Concat(handlerMetatdata, endpointMetadata).ToList(); } // Internal for unit testing internal static HandlerMethodDescriptor[] CreateHandlerMethods(PageApplicationModel applicationModel) { var handlerModels = applicationModel.HandlerMethods; var handlerDescriptors = new HandlerMethodDescriptor[handlerModels.Count]; for (var i = 0; i < handlerDescriptors.Length; i++) { var handlerModel = handlerModels[i]; handlerDescriptors[i] = new HandlerMethodDescriptor { HttpMethod = handlerModel.HttpMethod, Name = handlerModel.HandlerName, MethodInfo = handlerModel.MethodInfo, Parameters = CreateHandlerParameters(handlerModel), }; } return handlerDescriptors; } // internal for unit testing internal static HandlerParameterDescriptor[] CreateHandlerParameters(PageHandlerModel handlerModel) { var methodParameters = handlerModel.Parameters; var parameters = new HandlerParameterDescriptor[methodParameters.Count]; for (var i = 0; i < parameters.Length; i++) { var parameterModel = methodParameters[i]; parameters[i] = new HandlerParameterDescriptor { BindingInfo = parameterModel.BindingInfo, Name = parameterModel.ParameterName, ParameterInfo = parameterModel.ParameterInfo, ParameterType = parameterModel.ParameterInfo.ParameterType, }; } return parameters; } // internal for unit testing internal static PageBoundPropertyDescriptor[] CreateBoundProperties(PageApplicationModel applicationModel) { var results = new List<PageBoundPropertyDescriptor>(); var properties = applicationModel.HandlerProperties; for (var i = 0; i < properties.Count; i++) { var propertyModel = properties[i]; // Only add properties which are explicitly marked to bind. if (propertyModel.BindingInfo == null) { continue; } var descriptor = new PageBoundPropertyDescriptor { Property = propertyModel.PropertyInfo, Name = propertyModel.PropertyName, BindingInfo = propertyModel.BindingInfo, ParameterType = propertyModel.PropertyInfo.PropertyType, }; results.Add(descriptor); } return results.ToArray(); } }