HTTP POST가 오류 : 417“예상 실패”를 반환합니다.


212

URL에 POST를 시도하면 다음 예외가 발생합니다.

원격 서버가 오류를 반환했습니다 : (417) 예상 실패.

샘플 코드는 다음과 같습니다.

var client = new WebClient();

var postData = new NameValueCollection();
postData.Add("postParamName", "postParamValue");

byte[] responseBytes = client.UploadValues("http://...", postData);
string response = Encoding.UTF8.GetString(responseBytes); // (417) Expectation Failed.

HttpWebRequest/HttpWebResponse쌍을 사용 하거나 HttpClient차이를 만들지 않습니다.

이 예외의 원인은 무엇입니까?


2
응용 프로그램이 프록시 서버를 통해 통신 할 때 문제가 발생하는 것 같습니다. 내가 작성한 .NET 응용 프로그램은 인터넷에 직접 연결되었지만 프록시 서버 뒤에 있지 않을 때는 작동했습니다.
살만 A

2
클라이언트가 HTTP 1.0 (전용) 프록시 서버를 통해 실행될 때이 조건을 준수했습니다. 클라이언트 (구성이없는 asmx 프록시)가 HTTP 1.1 요청을 보내고 있으며 프록시가 (서버가 참여하기 전에) 프록시가 보내는 것을 거부합니다. 최종 사용자가 사용하여이 문제를 있으시면 아래의 설정 솔루션은 이 요청이 이해 프록시에 의존하지 않고 생성되도록 할 것 같은 적절한 해결 방법입니다 Expect기본적으로 추가됩니다 헤더 Expect100Continue이다 true기본적으로합니다.
Ruben Bartelink

답변:


478

이 정적 속성 을 false 로 설정하여 명시 적으로 요청하지 않는 한 System.Net.HttpWebRequest는 'HTTP 헤더 "예상 : 100- 계속"'헤더를 모든 요청에 ​​추가합니다 .

System.Net.ServicePointManager.Expect100Continue = false;

일부 서버는 해당 헤더를 질식시키고 현재보고있는 417 오류를 다시 보냅니다.

그 기회를 줘.


5
크리스마스 다음 날 갑자기 작동을 멈추는 트위터와 대화하는 코드가있었습니다. 서버가 해당 헤더에서 질식하기 시작한 업그레이드 또는 구성 변경을 수행했습니다. 수정 사항을 찾는 것은 고통이었습니다.
xcud

8
Jon Skeet이 솔루션을 게시 한 스레드에서 답변을 수락하기 위해 추가로 10 점을 얻었습니다.
xcud


25
app.config에서 해당 속성을 지정할 수도 있습니다 : <system.net> <settings> <servicePointManager expect100Continue = "false"/>. nahidulkibria.blogspot.com/2009/06/…
Andre Luus

2
참고 :이 설정은 ServiceReferences에도 적용되며 WebReferences를 가정합니다.
Myster

114

또 다른 방법 -

다음 행을 애플리케이션 구성 파일 구성 섹션에 추가하십시오.

<system.net>
    <settings>
        <servicePointManager expect100Continue="false" />
    </settings>
</system.net>

6
작동 변경을해야하고 코드 변경 준비가되지 않은 경우 매우 효과적입니다.
dawebber

1
그 구성 줄은 무엇을합니까?
J86

31

런타임시 다음과 같은 상황 및 오류가 기본 마법사에서 생성 된 SOAP 웹 서비스 프록시 (WCF System.ServiceModel스택 의 경우 100 %가 아님)에서도 발생할 수 있습니다 .

  • 최종 사용자 컴퓨터가 인터넷 설정에서 HTTP 1.1을 이해하지 못하는 프록시를 사용하도록 구성되었습니다.
  • (일반적으로는 A HTTP 1.0 프록시 나던 이해하는 것이 무엇인가 보내는 최대 클라이언트 종료 ExpectHTTP를의 일환으로 헤더 POST또는 PUT인해 두 부분으로 요청을 전송하는 표준 프로토콜 규칙에 요청 비고에 덮여 여기에 )

... 417을 산출합니다.

다른 답변에서 다루었 듯이, 특정 문제가 Expect헤더로 인해 문제가 발생하는 것이라면을 통해 두 부분으로 구성된 PUT / POST 전송의 상대적으로 전역 전환하여 특정 문제를 해결할 수 있습니다 System.Net.ServicePointManager.Expect100Continue.

그러나 이것은 완전한 근본적인 문제를 해결하지는 않습니다. 스택은 여전히 ​​KeepAlives 등과 같은 HTTP 1.1 관련 사항을 사용하고있을 수 있습니다 (많은 경우에 다른 답변이 주요 사례를 다루지 만).

그러나 실제 문제는 자동 생성 코드는 모든 사람들이 이것을 이해하면서 HTTP 1.1 기능을 맹목적으로 사용하는 것이 좋다고 가정한다는 것입니다. 특정 웹 서비스 프록시에 대해이 가정을 중지하기 위해이 게시물에 표시된대로 대체되는 파생 프록시 클래스를 작성 HttpWebRequest.ProtocolVersion하여 기본 1.1 에서 기본 기본 대체를 변경할 수 있습니다 .protected override WebRequest GetWebRequest(Uri uri)

public class MyNotAssumingHttp11ProxiesAndServersProxy : MyWS
{
    protected override WebRequest GetWebRequest(Uri uri)
    {
      HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
      request.ProtocolVersion = HttpVersion.Version10;
      return request;
    }
}

( MyWS웹 참조 추가 마법사가 표시되는 프록시가 있습니다.)


업데이트 : 프로덕션에서 사용하는 impl이 있습니다.

class ProxyFriendlyXXXWs : BasicHttpBinding_IXXX
{
    public ProxyFriendlyXXXWs( Uri destination )
    {
        Url = destination.ToString();
        this.IfProxiedUrlAddProxyOverriddenWithDefaultCredentials();
    }

    // Make it squirm through proxies that don't understand (or are misconfigured) to only understand HTTP 1.0 without yielding HTTP 417s
    protected override WebRequest GetWebRequest( Uri uri )
    {
        var request = (HttpWebRequest)base.GetWebRequest( uri );
        request.ProtocolVersion = HttpVersion.Version10;
        return request;
    }
}

static class SoapHttpClientProtocolRealWorldProxyTraversalExtensions
{
    // OOTB, .NET 1-4 do not submit credentials to proxies.
    // This avoids having to document how to 'just override a setting on your default proxy in your app.config' (or machine.config!)
    public static void IfProxiedUrlAddProxyOverriddenWithDefaultCredentials( this SoapHttpClientProtocol that )
    {
        Uri destination = new Uri( that.Url );
        Uri proxiedAddress = WebRequest.DefaultWebProxy.GetProxy( destination );
        if ( !destination.Equals( proxiedAddress ) )
            that.Proxy = new WebProxy( proxiedAddress ) { UseDefaultCredentials = true };
    }
}

2
나는 당신이 이것을 꽤 오래 전에 알았지 만 Ruben, 당신은 생명의 은인입니다. 이 문제는 귀하의 솔루션을 발견하고 완벽하게 작동 할 때까지 나를 미치게했습니다. 건배!
Christopher McAtackney

1
@ChrisMcAtackney 천만에요. 그것은 당시에 그것을 문서화하는 노력의 가치가있는 것처럼 보였습니다 ... 우선 순위 문제가되는 변두리 주위에 설정된 일반적인 문제는 제대로 조사 할 때까지 나를 귀찮게했지만 Google 주스는 없었습니다. 문제의 측면. 그리고 Attwood chap의 게시물 중 하나에서 나에게 그것을 밀어 넣었습니다. (이 같은 의견을 가진 upvote에이 BTW 환상적이다)
루벤 Bartelink

1
훌륭한 추가 및 예. 감사!
Fadi Chamieh

5

에뮬레이션하려는 양식에 사용자 이름과 비밀번호라는 두 개의 필드가 있습니까?

그렇다면이 줄 :

 postData.Add("username", "password");

정확하지 않습니다.

다음과 같은 두 줄이 필요합니다.

 postData.Add("username", "Moose");
postData.Add("password", "NotMoosespasswordreally");

편집하다:

자, 이것이 문제가 아니기 때문에 이것을 해결하는 한 가지 방법은 Fiddler 또는 Wireshark와 같은 것을 사용하여 브라우저에서 웹 서버로 전송되는 것을보고 코드에서 전송 된 것과 비교하는 것입니다. .Net에서 일반 포트 80으로 이동하는 경우 Fiddler는 여전히이 트래픽을 캡처합니다.

웹 서버가 보내지 않을 것으로 예상되는 양식에 다른 숨겨진 필드가있을 수 있습니다.


3

프록시 측의 해결책으로 SSL 핸드 셰이크 프로세스에서 몇 가지 문제에 직면했으며 프록시 서버가 HTTP / 1.0을 사용하여 요청을 보내서 문제를 해결하기 위해 httpd.conf 에서이 인수를 설정 SetEnv force-proxy-request-1.0 1 SetEnv proxy-nokeepalive 1하여 417 오류에 직면 한 후 내 클라이언트 응용 프로그램이 HTTP / 1.1을 사용하고 프록시가 HTTP / 1.0을 사용하도록 강요 RequestHeader unset Expect early했지만 클라이언트 측에서 아무것도 변경할 필요없이 프록시 측의 httpd.conf 에서이 매개 변수를 설정하여 문제가 해결되었습니다. .


2

Powershell의 경우

[System.Net.ServicePointManager]::Expect100Continue = $false

1

" HttpClient "를 사용 중이고 전역 구성을 사용하여 모든 프로그램에 영향을 미치지 않으려면 다음을 사용할 수 있습니다.

 HttpClientHandler httpClientHandler = new HttpClientHandler();
 httpClient.DefaultRequestHeaders.ExpectContinue = false;

" WebClient "를 사용하고 있습니다. 다음을 호출하여이 헤더를 제거 할 수 있다고 생각합니다.

 var client = new WebClient();
 client.Headers.Remove(HttpRequestHeader.Expect);

0

내 상황 에서이 오류는 클라이언트 컴퓨터에 엄격한 방화벽 정책이있는 경우에만 발생하여 프로그램이 웹 서비스와 통신하지 못하게합니다.

따라서 내가 찾을 수있는 유일한 해결책은 오류를 포착하고 방화벽 설정을 수동으로 변경하는 방법을 사용자에게 알리는 것입니다.


-1

web.config 접근 방식은 IntApp 웹 서비스 사용 규칙에 대한 InfoPath 양식 서비스 호출에 사용됩니다.

  <system.net>
    <defaultProxy />
    <settings> <!-- 20130323 bchauvin -->
        <servicePointManager expect100Continue="false" />
    </settings>
  </system.net>

2
dup of stackoverflow.com/a/7358457/11635 포인트를 추가하려면 여기에 의견을 남겨주세요
Ruben Bartelink
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.