内部处理程序未使用WebApi委托处理程序分配

20

我在代码中遇到了 WebApi 抛出异常的问题:

public class WebApiAuthenticationHandler : DelegatingHandler
    {
        private const string AuthToken = "AUTH-TOKEN";

        protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
        {                  
            var requestAuthTokenList = GetRequestAuthTokens(request);
            if (ValidAuthorization(requestAuthTokenList))
            {
                // EXCEPTION is occuring here!....
                return base.SendAsync(request, cancellationToken);
            }

            /*
            ** This will make the whole API protected by the API token.
            ** To only protect parts of the API then mark controllers/methods
            ** with the Authorize attribute and always return this:
            **
            ** return base.SendAsync(request, cancellationToken);
            */
            return Task<HttpResponseMessage>.Factory.StartNew(
                () =>
                {
                    var resp = new HttpResponseMessage(HttpStatusCode.Unauthorized)
                    {
                        Content = new StringContent("Authorization failed")
                    };

                    //var resp = new HttpResponseMessage(HttpStatusCode.Unauthorized);                                                                                   
                    //resp.Headers.Add(SuppressFormsAuthenticationRedirectModule.SuppressFormsHeaderName,"true");
                    return resp;
                });
        }

异常发生在这一行:

base.SendAsync(request, cancellationToken);

我不知道如何修复这个问题。我在我的路由表中有以下内容:

    routes.MapHttpRoute("NoAuthRequiredApi", "api/auth/", new { Controller = "Auth" });
    routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional }, null, new WebApiAuthenticationHandler());

发生这种情况的路由是DefaultApi路由。非常感谢任何帮助...

3个回答

41

找到答案在这里,以及一个示例处理程序在这里

你需要设置你想要请求传递到的 InnerHandler。

只需将以下内容添加到您的构造函数:

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

在创建新实例时,传递GlobalConfiguration的引用:

routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional }, null, WebApiAuthenticationHandler(GlobalConfiguration.Configuration));

15
在 ASP Core 2.1 中,'InnerHandler = new HttpClientHandler();' 似乎是有效的。 - Neutrino
我发现我必须在构造函数中进行赋值,否则会出现只读错误。 - Darryl Wagoner WA1GON
顶部的两个链接都失效了。有人有更新的链接吗? - Narshe

5
根据链接当前得票最高答案中提到的(由Daniel Roth提到),你的处理程序链不能以DelegatingHandler终止。

DelegatingHandler将发送调用委托给使用InnerHandler属性提供的内部处理程序。DelegatingHandler用于在俄罗斯套娃模型中链接消息处理程序。错误消息表示未提供InnerHandler。通常,在客户端上,希望最内部的处理程序是HttpClientHandler,它将将请求传输到网络并处理响应。

解决此错误的最简单方法是使用构造函数重载来设置InnerHandler,如下所示:
public class CustomHandler : DelegatingHandler
{
    public CustomHandler()
        : base(new HttpClientHandler())
    {
    }
}

没有必要传入一个 HttpConfiguration 并将其包装在一个 HttpControllerDispatcher 中。


3
有时候你需要检查一下你请求的RESTful Url是否真的存在于你的控制器中。我曾经遇到过这种异常,原因是URL匹配错误。谢谢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接