【问题标题】:The 'DelegatingHandler' list is invalid because the property 'InnerHandler' of 'handler' is not null'DelegatingHandler' 列表无效,因为 'handler' 的属性 'InnerHandler' 不为空
【发布时间】:2017-06-12 21:14:52
【问题描述】:

我有一个全局添加的自定义消息处理程序,如下所示:

public class CustomerHandler : DelegatingHandler
{
    public CustomHandler(HttpConfiguration httpConfiguration)
    {
        InnerHandler = new HttpControllerDispatcher(httpConfiguration); 
    }
}

config.MessageHandlers.Add(new CustomHandler(config));

但是,我收到以下错误:

“DelegatingHandler”列表无效,因为“CustomHandler”的属性“InnerHandler”不为空。 参数名称:handlers

所以我把代码改成:

config.MessageHandlers.Add(new CustomHandler(config) { InnerHandler = null });

我得到一个错误:

ArgumentNullException

当我将处理程序添加到单个路由时,它工作正常。

var customHandler = new CustomHandler(config);

config.Routes.MapHttpRoute(
  name: "default",
  routeTemplate: "api/{controller}/{id}",
  defaults: new { id = RouteParameter.Optional },
  constraints: new { id = @"^[0-9]+$" },
  handler: customHandler
);

因此,当Innerhandler 设置正确或为空时,它总是会引发异常。

我错过了什么?

编辑

此自定义处理程序用于检查请求中是否存在特定标头,如果找到,则从内存缓存中获取用户详细信息。从处理程序更改为模块是否更有意义?

【问题讨论】:

    标签: c# asp.net-web-api asp.net-web-api2 asp.net-web-api-routing


    【解决方案1】:

    首先您应该阅读HTTP Message Handlers in ASP.NET Web API 以更好地了解处理程序。

    消息处理程序的调用顺序与它们出现的顺序相同 MessageHandlers 集合。因为它们是嵌套的,所以响应 消息向另一个方向传播。也就是说,最后一个处理程序是 第一个收到响应消息。

    请注意,您不需要设置内部处理程序;网络 API 框架自动连接消息处理程序。

    如果打算将处理程序添加到管道,则不应设置内部处理程序。框架将根据委托处理程序添加到管道的顺序来执行此操作。

    当直接将处理程序添加到路由时,不需要内部处理程序,这就是它按照您在 OP 中所述工作的原因。

    【讨论】:

    • 除了WebAPI,我扩展了HttpClient,我得到了这个错误......我的意思是,什么时候应该真正设置innerHandler呢?为什么这个ctor存在?
    【解决方案2】:

    当您在批处理或循环中重复使用相同的“处理程序”实例时,通常会发生此错误。

    在每个请求结束时正确处理 HttpClient 可确保您始终从头开始:

            using (var client = new HttpClient(
                    HttpClientFactory.CreatePipeline(
                    new HttpClientHandler
                    {
                        CookieContainer = new CookieContainer(),
                        UseCookies = true
                    },
                    new DelegatingHandler[] { new CustomHandler() })))
            {
    
                var content = new StringContent(request, Encoding.UTF8,"text/xml");
    
                using (var response = await client.PostAsync(requestUrl, content))
                {
                    // DO response processing
                }
            }
    

    希望这能有所帮助。

    【讨论】:

    • 不建议丢弃HttpClient。 “作为第一个问题,虽然这个类是一次性的,但在 using 语句中使用它并不是最佳选择,因为即使您处理 HttpClient 对象,底层套接字也不会立即释放,并可能导致名为“套接字耗尽”的严重问题。 " ...“因此,HttpClient 旨在被实例化一次并在应用程序的整个生命周期中重复使用。” docs.microsoft.com/en-us/dotnet/architecture/microservices/…
    【解决方案3】:

    在我的情况下,我收到了该错误消息,因为由于配置错误导致多次调用下面的 RegisterGlobalFilters 方法,因此处理程序被两次添加到 MessageHandlers。只需确保只添加一次即可。

    using System.Web.Http;
    ...
    public static void RegisterGlobalFilters(HttpConfiguration httpConfiguration)
    {
        httpConfiguration.MessageHandlers.Add(new MyDelegatingHandler());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-12
      • 2020-09-08
      • 2022-07-27
      • 2012-05-05
      • 2022-01-01
      • 2019-04-29
      • 1970-01-01
      • 2021-04-19
      相关资源
      最近更新 更多