SassKit. Мультитенантность не совместима с AspNetCore 2.2? - PullRequest
2 голосов
/ 22 апреля 2019

Я создал .NET Core API Controller, и в методе POST я пытаюсь использовать метод CreatedAtActionResult , чтобы включить маршрут в качестве заголовка расположения в мой ответ.

[ApiController, Route("v1/[controller]")]
public class WidgetController: ControllerBase
{
    public WidgetController(IWidgetService service)
    {
        _service = service;
    }

    private readonly IWidgetService _service;

    [HttpGet("{id}", Name = "GetSingle")]
    public IActionResult GetSingle(Guid id)
    {
        var result = _service.Get(id);

        return Ok(result);
    }

    [HttpPost]
    public IActionResult Post(WidgetModel model)
    {
        var result = _service.Post(model);

        return result == Guid.Empty
                    ? (IActionResult) BadRequest("No changes saved.")
                    : CreatedAtAction(nameof(GetSingle),
                                      new {id = result},
                                      model);
    }
}

Когда я запускаю приложение, первый вызов POST из POSTman выполняется без проблем. И объект, и URL-адрес заголовка расположения генерируются, как и ожидалось. Однако, если я попытаюсь достичь этой конечной точки во второй раз, пока код еще работает, я получаю следующую ошибку:

System.InvalidOperationException: нет службы для типа 'Microsoft.AspNetCore.Routing.IEndpointAddressScheme 1[Microsoft.AspNetCore.Routing.RouteValuesAddress]' has been registered. at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.AspNetCore.Routing.DefaultLinkGenerator.GetEndpoints[TAddress](TAddress address) at Microsoft.AspNetCore.Routing.DefaultLinkGenerator.GetPathByAddress[TAddress](HttpContext httpContext, TAddress address, RouteValueDictionary values, RouteValueDictionary ambientValues, Nullable 1 pathBase, фрагмент FragmentString, параметры LinkOptions) в Microsoft.AspNetCore.Routing.LinkGeneratorRouteValuesAddressExtensions.GetPathByRouteValues ​​(Генератор LinkGenerator, HttpContext httpContext, String routeName, Значения объекта, Nullable 1 pathBase, FragmentString fragment, LinkOptions options) at Microsoft.AspNetCore.Mvc.Routing.EndpointRoutingUrlHelper.Action(UrlActionContext urlActionContext) at Microsoft.AspNetCore.Mvc.UrlHelperExtensions.Action(IUrlHelper helper, String action, String controller, Object values, String protocol, String host, String fragment) at Microsoft.AspNetCore.Mvc.UrlHelperExtensions.Action(IUrlHelper helper, String action, String controller, Object values, String protocol, String host) at Microsoft.AspNetCore.Mvc.CreatedAtActionResult.OnFormatting(ActionContext context) at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync(ActionContext context, ObjectResult result) at Microsoft.AspNetCore.Mvc.ObjectResult.ExecuteResultAsync(ActionContext context) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext) at SaasKit.Multitenancy.Internal.TenantResolutionMiddleware 1.Invoke (контекст HttpContext, ITververantRol) в Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke (контекст HttpContext)

Я пытался заменить CreatedAtAction на Ok, и результат 200 будет возвращаться столько раз, сколько я нажимаю кнопку в POSTman.

Код внутри метода Post успешно обрабатывается, и он переходит к методу OnActionExecuted созданного мной фильтра. Я попытался просмотреть все свойства объекта ActionExecutedContext и не вижу ничего необычного. Как только я выйду из этого пустого метода OnActionExecuted, вызов возвращает код состояния 500 и приведенную выше трассировку стека на странице ошибок. У меня есть фильтр исключений, но он не затрагивается.

У кого-нибудь были проблемы с этим раньше?

Для справки, вот моя конфигурация запуска:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddMultitenancy<AppTenant, CachingAppTenantResolver>();

    services.AddAutoMapper()
            .AddSingleton(ConfigureAutoMapper())
            .AddMvc(options =>
            {
                options.Filters.Add<ValidatorActionFilter>();
                options.Filters.Add<ErrorHandlingFilter>();
            })
            .AddFluentValidation(validation => {
                validation.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
                validation.ImplicitlyValidateChildProperties = true;
                validation.RegisterValidatorsFromAssemblyContaining<WidgetModelValidator>();
                })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressModelStateInvalidFilter = true;
                options.SuppressMapClientErrors = true;
            });

    services.AddEntityFrameworkSqlServer()
            .AddDbContext<MyContext>();

    services.Configure<MultitenancyOptions>(configuration.GetSection("Multitenancy"));

    services.AddCors(options =>
    {
        options.AddDefaultPolicy(
            builder =>
            {
                builder.WithOrigins("http://localhost:4200").AllowAnyHeader().AllowAnyMethod();
            });
    });

    ConfigureContainer(container);

    return provider;
}

1 Ответ

1 голос
/ 23 апреля 2019

Попробуйте установить CompatibilityVersion.Version_2_0 или 2.1 вместо 2.2?

EndpointRouting довольно сильно изменился под покровом 2.2, и ваше стороннее дополнение может быть несовместимо.

Установка совместимости обратно на 2.1, как правило, не потребует каких-либо изменений кода в вашем контроллере, так что это довольно дешево.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...