【问题标题】:SassKit.Multitenancy not compatible with AspNetCore 2.2?SaasKit.Multitenancy 与 Asp Net Core 2.2 不兼容?
【发布时间】:2019-04-22 16:53:50
【问题描述】:

我创建了一个 .NET Core API 控制器,并且在 POST 方法中,我尝试使用 CreatedAtActionResult 方法将路由作为 Location Header 包含在我的响应中。

[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);
    }
}

当我启动应用程序时,POSTman 对 POST 的第一次调用运行没有问题。对象和位置标头 URL 都按预期生成。但是,如果我在代码仍在运行时再次尝试访问该端点,则会收到以下错误:

System.InvalidOperationException:没有服务类型为“Microsoft.AspNetCore.Routing.IEndpointAddressScheme1[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, Nullable1 pathBase、FragmentString 片段、LinkOptions 选项) 在 Microsoft.AspNetCore.Routing.LinkGeneratorRouteValuesAddressExtensions.GetPathByRouteValues(LinkGenerator 生成器,HttpContext httpContext,字符串 routeName,对象值,Nullable1 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.TenantResolutionMiddleware1.Invoke(HttpContext 上下文,ITenantResolver`1 tenantResolver) 在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文)

我已经尝试将CreatedAtAction 替换为Ok,并且在我单击POSTman 中的按钮时,200 结果将返回。

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;
}

【问题讨论】:

  • 我没有;但是否也有可能发布您的 Startup.ConfigureServices() 可能是相关的?第二次调用的错误肯定会让我们认为涉及到服务生命周期。和/或新的 EndpointPointRouting 可能存在一些问题
  • 好点。我忘了包括那个。谢谢你,@ChrisFCarroll
  • 所以我可能在这里叫错了树,但我的下一个诊断步骤是,删除“跨调用保存信息”的 2 个嫌疑人:删除 CachingAppTenantResolver 并使单例 AutoMapper 成为临时依赖项反而。看看这是否会给你带来不同的错误信息?
  • 另一个想法:当您尝试 CompatibilityVersion.Version_2_0 或 2.1 而不是 2.2 时会发生什么? (EndpointRouting 仅随 2.2 提供,您的控制器应该在 2.1 或 2.0 下正常工作)。如果您的租约是第 3 方的东西,它可能还不兼容 2.2?
  • MS 仍在征求有关端点路由的错误和反馈——他们可能仍然很高兴收到错误报告。它认为 t 旨在向后兼容

标签: c# asp.net-core


【解决方案1】:

尝试设置CompatibilityVersion.Version_2_02.1 而不是2.2

EndpointRouting 在 2.2 的覆盖下是一个相当大的变化,您的 3rd 方插件可能不兼容。

将兼容性设置回 2.1 通常不需要在控制器中更改任何代码,因此成本相当低。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2020-01-02
    • 1970-01-01
    • 2017-04-23
    相关资源
    最近更新 更多