/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Mvc/test/Mvc.IntegrationTests/ModelBindingTestHelper.cs
231 строка
8 KB
Bruno Oliveira
Allowing empty FromBody parameters input based on nullability (#39917)
24 фев 2022, 22:24
Не верифицирован
24 фев 2022, 22:24
c72f78e
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.Mvc.IntegrationTests; public static class ModelBindingTestHelper { public static ModelBindingTestContext GetTestContext( Action<HttpRequest> updateRequest = null, Action<MvcOptions> updateOptions = null, ControllerActionDescriptor actionDescriptor = null, IModelMetadataProvider metadataProvider = null, MvcOptions mvcOptions = null) { var httpContext = GetHttpContext(metadataProvider, updateRequest, updateOptions, mvcOptions); var services = httpContext.RequestServices; metadataProvider = metadataProvider ?? services.GetRequiredService<IModelMetadataProvider>(); var options = services.GetRequiredService<IOptions<MvcOptions>>(); var context = new ModelBindingTestContext { ActionDescriptor = actionDescriptor ?? new ControllerActionDescriptor(), HttpContext = httpContext, MetadataProvider = metadataProvider, MvcOptions = options.Value, RouteData = new RouteData(), ValueProviderFactories = new List<IValueProviderFactory>(options.Value.ValueProviderFactories), }; return context; } public static ParameterBinder GetParameterBinder( MvcOptions options = null, IModelBinderProvider binderProvider = null) { if (options == null) { var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); return GetParameterBinder(metadataProvider, binderProvider); } else { var metadataProvider = TestModelMetadataProvider.CreateProvider(options.ModelMetadataDetailsProviders); return GetParameterBinder(metadataProvider, binderProvider, options); } } public static ParameterBinder GetParameterBinder(ModelBindingTestContext testContext) { return GetParameterBinder(testContext.HttpContext.RequestServices); } public static ParameterBinder GetParameterBinder(IServiceProvider serviceProvider) { var metadataProvider = serviceProvider.GetRequiredService<IModelMetadataProvider>(); var options = serviceProvider.GetRequiredService<IOptions<MvcOptions>>(); return new ParameterBinder( metadataProvider, new ModelBinderFactory(metadataProvider, options, serviceProvider), new DefaultObjectValidator( metadataProvider, new[] { new CompositeModelValidatorProvider(GetModelValidatorProviders(options)) }, options.Value), options, NullLoggerFactory.Instance); } public static ParameterBinder GetParameterBinder( IModelMetadataProvider metadataProvider, IModelBinderProvider binderProvider = null, MvcOptions mvcOptions = null, ObjectModelValidator validator = null) { var services = GetServices(metadataProvider, mvcOptions: mvcOptions); var options = services.GetRequiredService<IOptions<MvcOptions>>(); if (binderProvider != null) { options.Value.ModelBinderProviders.Insert(0, binderProvider); } validator ??= new DefaultObjectValidator( metadataProvider, new[] { new CompositeModelValidatorProvider(GetModelValidatorProviders(options)) }, options.Value); return new ParameterBinder( metadataProvider, new ModelBinderFactory(metadataProvider, options, services), validator, options, NullLoggerFactory.Instance); } public static IModelBinderFactory GetModelBinderFactory( IModelMetadataProvider metadataProvider, IServiceProvider services = null) { if (services == null) { services = GetServices(metadataProvider); } var options = services.GetRequiredService<IOptions<MvcOptions>>(); return new ModelBinderFactory(metadataProvider, options, services); } public static IObjectModelValidator GetObjectValidator( IModelMetadataProvider metadataProvider, IOptions<MvcOptions> options = null) { return new DefaultObjectValidator( metadataProvider, GetModelValidatorProviders(options), options?.Value ?? new MvcOptions()); } private static IList<IModelValidatorProvider> GetModelValidatorProviders(IOptions<MvcOptions> options) { if (options == null) { return TestModelValidatorProvider.CreateDefaultProvider().ValidatorProviders; } else { return options.Value.ModelValidatorProviders; } } private static HttpContext GetHttpContext( IModelMetadataProvider metadataProvider, Action<HttpRequest> updateRequest = null, Action<MvcOptions> updateOptions = null, MvcOptions mvcOptions = null) { var httpContext = new DefaultHttpContext(); httpContext.Features.Set<IHttpRequestLifetimeFeature>(new CancellableRequestLifetimeFeature()); httpContext.Features.Set<IHttpRequestBodyDetectionFeature>(new NonZeroContentLengthRequestBodyDetectionFeature(httpContext)); updateRequest?.Invoke(httpContext.Request); httpContext.RequestServices = GetServices(metadataProvider, updateOptions, mvcOptions); return httpContext; } public static IServiceProvider GetServices( IModelMetadataProvider metadataProvider, Action<MvcOptions> updateOptions = null, MvcOptions mvcOptions = null) { var serviceCollection = new ServiceCollection(); serviceCollection.AddSingleton(new ApplicationPartManager()); if (metadataProvider != null) { serviceCollection.AddSingleton(metadataProvider); } else if (updateOptions != null || mvcOptions != null) { serviceCollection.AddSingleton(services => { var optionsAccessor = services.GetRequiredService<IOptions<MvcOptions>>(); return TestModelMetadataProvider.CreateProvider(optionsAccessor.Value.ModelMetadataDetailsProviders); }); } else { serviceCollection.AddSingleton<IModelMetadataProvider>(services => { return TestModelMetadataProvider.CreateDefaultProvider(); }); } if (mvcOptions != null) { serviceCollection.AddSingleton(Options.Create(mvcOptions)); } serviceCollection.AddMvc() .AddNewtonsoftJson(); serviceCollection .AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance) .AddTransient<ILogger<DefaultAuthorizationService>, Logger<DefaultAuthorizationService>>(); if (updateOptions != null) { serviceCollection.Configure(updateOptions); } return serviceCollection.BuildServiceProvider(); } private class CancellableRequestLifetimeFeature : IHttpRequestLifetimeFeature { private readonly CancellationTokenSource _cts = new CancellationTokenSource(); public CancellationToken RequestAborted { get => _cts.Token; set => throw new NotImplementedException(); } public void Abort() { _cts.Cancel(); } } private class NonZeroContentLengthRequestBodyDetectionFeature : IHttpRequestBodyDetectionFeature { private readonly HttpContext _context; public NonZeroContentLengthRequestBodyDetectionFeature(HttpContext context) { _context = context; } public bool CanHaveBody => _context.Request.ContentLength != 0; } }