EIdHTTPProtocolException不会引发异常

时间:2016-05-24 09:23:00

标签: delphi indy delphi-xe4

我尝试使用身份验证过滤器在网络mvc app webapi(.net和c#)上发布来自旧delphi应用程序的数据。如果密码错误,则返回401,但不引发异常,结果为空。现在我被迫手动检查响应代码! 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;

1 个答案:

答案 0 :(得分:2)

响应代码401 NOT 是HTTP错误,这就是为什么EIdHTTPProtocolException不会立即引发的原因。 401是服务器向客户端请求身份验证凭据的方式。 TIdHTTP通过检查以下标准来处理401:

  1. 认证尝试次数尚未超过TIdHTTP.MaxAuthRetries属性的值(默认为3)。

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

  3. 分配了TIdHTTP.OnAuthorization事件处理程序,并在其Handled输出参数中返回True(从用户获取更新的凭据后),或TIdHTTP.Request.Password属性不为空。

  4. 所选授权方案尚未用完(BASIC为1,NTLM为3等)。

  5. 如果上述任何条件不合适,则会引发EIdHTTPProtocolException,除非您:

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

    2. AIgnoreReplies的{​​{1}}参数中指定401(TIdHTTP.DoRequest()不会公开该参数,但TIdHTTP.Post()会公开。

    3. 在其中任何一种情况下,当前请求只是没有错误地结束,您必须手动检查TIdHTTP.Get()属性。

      另一方面,如果上述条件正常,并且TIdHTTP.ResponseCode属性中启用了hoInProcessAuth参数,则会使用(可能更新的)身份验证凭据重试当前请求。但是如果未启用TIdHTTP.HTTPOptions,则当前请求将立即结束而不会出现错误,您必须手动检查hoInProcessAuth属性。默认情况下未启用TIdHTTP.ResponseCode,因此这是您hoInProcessAuth请求结束的可能分支。

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

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