EIdHTTPProtocolException 不会引发异常

EIdHTTPProtocolException doesn't raise exception

我正在尝试 post 带有身份验证过滤器的 web mvc 应用程序 webapi(.net 和 c#)上旧 delphi 应用程序的数据。如果密码错误return401但没有抛出异常,结果为空。现在我被迫手动检查响应代码! HTTPOptions 没问题。

try
  Result := IdHTTP.Post(requestUrl, JsonToSend);
  //In this way I fixed this problem but it's very annoying! :(
  //if (IdHTTP.ResponseCode<>200) then  raise Exception.Create(IdHTTP.ResponseText);
except
  on E: EIdHTTPProtocolException do
    begin
      raise Exception.Create(E.Message);
    end;
  on E : Exception do
    raise Exception.Create(e.Message);
end;

响应代码 401 不是 HTTP 错误,这就是 EIdHTTPProtocolException 没有立即引发的原因。 401 是服务器向客户端询问身份验证凭据的方式。 TIdHTTP 通过检查以下条件来处理 401:

  1. 认证尝试次数还没有超过TIdHTTP.MaxAuthRetries属性的值(默认3)。

  2. TIdHTTP.Response.WWWAuthenticate 属性 指定了 TIdHTTP 识别的身份验证方案,或者分配了 TIdHTTP.OnSelectAuthorization 事件处理程序并且 returns在其 AuthenticationClass 输出参数中的身份验证 class 类型。

  3. 一个 TIdHTTP.OnAuthorization 事件处理程序被分配并且 returns True 在它的 Handled 输出参数中(在从用户那里获得更新的凭据之后),或者 TIdHTTP.Request.Password属性不为空

  4. 所选的授权方案尚未 运行 步(1 个用于 BASIC,3 个用于 NTLM,等等)。

如果上述任何条件不符合,那么 EIdHTTPProtocolException 将被提升,除非您:

  1. 启用 TIdHTTP.HTTPOptions 属性 中的 hoNoProtocolErrorException 标志。

  2. TIdHTTP.DoRequest()AIgnoreReplies 参数中指定 401(TIdHTTP.Post() 不公开该参数,但 TIdHTTP.Get() 公开)。

在任何一种情况下,当前请求都会无错误地结束,您将不得不手动检查 TIdHTTP.ResponseCode 属性.

另一方面,如果上述条件正常,并且 TIdHTTP.HTTPOptions 属性 中启用了 hoInProcessAuth 参数,则重试当前请求(可能更新) 身份验证凭据。但是如果hoInProcessAuth没有启用,那么当前的请求就直接无误结束,你将不得不手动检查TIdHTTP.ResponseCode属性。默认情况下未启用 hoInProcessAuth,因此这可能是您的 Post 请求结束的分支。

服务器返回 401 的事实意味着服务器需要身份验证,因此您应该处理它。启用 hoInProcessAuth 并根据需要处理 OnSelectAuthorizationOnAuthorization 事件,以便每次用户提供新凭据时都可以重试请求。

但是,如果您真的希望 401 引发异常,请启用 hoInProcessAuth 并且根本不处理事件。或者,继续做你已经在做的事情。