HTTP POST Döndürme Hatası: 417 “Beklenti Başarısız.”


212

Bir URL'ye POST yapmaya çalıştığımda, aşağıdaki istisna ile sonuçlanır:

Uzak sunucu bir hata döndürdü: (417) Beklenti Başarısız.

İşte bir örnek kod:

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.

Bir HttpWebRequest/HttpWebResponseçift ​​ya da bir çift kullanmak HttpClientfark etmez.

Bu istisnanın nedeni nedir?


2
Sorun, uygulamanız bir proxy sunucusu üzerinden iletişim kurduğunda ortaya çıkıyor. Yazdığım bir .NET uygulaması doğrudan internete bağlıyken çalıştı, ancak bir proxy sunucusunun arkasındayken çalışmadı.
Salman A

2
İstemci bir HTTP 1.0 (yalnızca) proxy sunucusu üzerinden çalışırken bu koşulu gözlemledi. İstemci (herhangi bir yapılandırma olmadan asmx proxy'si) bir HTTP 1.1 isteği gönderir ve proxy (herhangi bir sunucu dahil olmadan önce) daha sonra proxy'nin ne gönderdiğini reddeder. Son kullanıcı bu sorunu yaşıyorsa, aşağıdaki yapılandırma çözümünün kullanılması, Expectvarsayılan olarak Expect100Continueolduğu gibi truevarsayılan olarak eklenen üstbilgiyi anlayan proxy'ye güvenmeden isteklerin oluşturulmasına neden olacağı için uygun bir çözümdür .
Ruben Bartelink

Yanıtlar:


478

System.Net.HttpWebRequest, bu statik özelliği false olarak ayarlayarak açıkça istemediğiniz sürece, her isteğe 'HTTP üstbilgisi "Expect: 100-Continue"' üstbilgisini ekler :

System.Net.ServicePointManager.Expect100Continue = false;

Bazı sunucular bu üstbilgiyi boğar ve gördüğünüz 417 hatasını geri gönderir.

Bir şans ver.


5
Aniden Noel'den sonraki gün çalışmayı bırakan Twitter'la konuşan bir kodum vardı. Sunucularının bu başlıkta boğulmaya başlamasına neden olan bir yükseltme veya yapılandırma değişikliği yapmışlardı. Düzeltmeyi bulmak acı vericiydi.
xcud

8
Sanırım Jon Skeet'in bir çözüm gönderdiği bir konuda kabul edilen bir cevap almak için fazladan 10 puan aldım.
xcud


25
Bu özelliği app.config dosyanızda da belirtebilirsiniz: <system.net> <settings> <servicePointManager wait100Continue = "false" />. nahidulkibria.blogspot.com/2009/06/…
Andre Luus

2
Not: Bu ayar ServiceReferences için de geçerlidir ve WebReferences olduğunu varsayıyorum.
Myster

114

Diğer yol -

Bu satırları uygulama yapılandırma dosyası yapılandırma bölümüne ekleyin:

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

6
Operasyonel bir değişiklik yapmanız gerektiğinde ve kod değişikliğine hazır olmadığınızda çok iyi çalışır.
dawebber

1
Bu yapılandırma satırı ne yapar?
J86

31

Aynı durum ve hata System.ServiceModel, çalışma zamanında varsayılan bir sihirbaz tarafından oluşturulan SOAP Web Hizmeti proxy'si (WCF yığınında da durum böyle ise% 100 değil) ile ortaya çıkabilir :

  • son kullanıcı makinesi (İnternet Ayarlarında) HTTP 1.1'i anlamayan bir proxy kullanacak şekilde yapılandırılmıştır
  • istemci, HTTP 1.0 proxy'sinin anlamadığı bir şey gönderir (genellikle buradaki Açıklamalar bölümünde açıklandığı gibi isteği iki bölüm halinde göndermek için standart bir protokol kuralı nedeniyle Expectbir HTTP POSTveya PUTisteğin bir parçası olarak bir başlık )

... 417 veriyor.

Diğer cevaplarda da belirtildiği gibi, karşılaştığınız belirli bir sorun Expectbaşlıkta soruna neden oluyorsa, söz konusu sorun, iki parçalı PUT / POST iletiminin göreceli olarak küresel bir şekilde kapatılmasıyla giderilebilir System.Net.ServicePointManager.Expect100Continue.

Ancak bu, altta yatan sorunun tamamını çözmez - yığın hala KeepAlives vb.Gibi HTTP 1.1'e özgü şeyler kullanıyor olabilir (ancak çoğu durumda diğer cevaplar ana vakaları kapsar).

Ancak asıl sorun, otomatik olarak oluşturulan kodun, herkesin anladığı gibi HTTP 1.1 olanaklarını körü körüne kullanmanın uygun olduğunu varsaymasıdır. Belirli bir Web Hizmeti proxy'si için bu varsayımı durdurmak için, bu yayında gösterildiği gibi geçersiz kılınan türetilmiş bir Proxy sınıfı oluşturarak varsayılanın altında yatan HttpWebRequest.ProtocolVersionvarsayılan değer olan 1.1'i geçersiz kılabilirsiniz : -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;
    }
}

( MyWSWeb Referansı Ekleme sihirbazının size tükettiği proxy nerede .)


GÜNCELLEME: İşte üretimde kullandığım bir 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
Bunu bir süre önce yayınladığını biliyorum, ama Ruben, sen hayat kurtarıcısın. Çözümünüzle karşılaşana kadar bu sorun beni deli ediyor ve mükemmel çalışıyor. Şerefe!
Christopher McAtackney

1
@ChrisMcAtackney Rica ederim. Kesinlikle onlara belgelemek için çabaya değer görünüyordu ... Genel sorun, öncelikli bir sorun haline gelmenin saçaklarının etrafında belirlendi ve düzgün bir şekilde araştırıncaya kadar beni rahatsız etti - ancak herhangi bir google suyu yoktu konunun o tarafı. ve Attwood ahbapının geri gönderdiği mesajlardan biriydi ve bu beni yapmaya itti. (Böyle bir yorumu içeren bir oylama fantastik
BTW'dir

1
Harika ekleme ve örnekler. Teşekkürler!
Fadi Chamieh

5

Taklit etmeye çalıştığınız formun kullanıcı adı ve şifre olmak üzere iki alanı var mı?

Öyleyse, bu satır:

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

Doğru değil.

iki satıra ihtiyacınız vardır:

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

Düzenle:

Tamam, bu sorun olmadığından, bununla başa çıkmanın bir yolu, Fiddler veya Wireshark gibi bir şeyi tarayıcıdan web sunucusuna gönderilenleri başarıyla izlemek, ardından bunu kodunuzdan gönderilenlerle karşılaştırmaktır. Net'ten normal bir bağlantı noktası 80'e gidiyorsanız, Fiddler yine de bu trafiği yakalayacaktır.

Formda, web sunucusunun göndermediğinizi beklediği başka bir gizli alan olabilir.


3

Proxy tarafında çözüm, SSL el sıkışma sürecinde bazı sorunlarla karşılaştım ve proxy sunucumu HTTP / 1.0 kullanarak istekleri göndermeye zorlamak zorunda kaldım, SetEnv force-proxy-request-1.0 1 SetEnv proxy-nokeepalive 1sonra bu argümanı httpd.conf'da ayarlayarak 417 hatasıyla karşılaştım. benim istemci uygulama HTTP / 1.1 kullanıyordu ve proxy HTTP / 1.0 kullanmak zorunda kaldı, sorun RequestHeader unset Expect earlyistemci tarafında bir şey değiştirmek gerek kalmadan proxy tarafında httpd.conf bu parametre ayarlanarak çözüldü , umarım bu yardımcı olur .


2

Powershell için

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

1

" HttpClient " kullanıyorsanız ve programınızın tümünü etkilemek için genel yapılandırmayı kullanmak istemiyorsanız:

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

" WebClient " kullanıyorum Sanırım bu üstbilgiyi arayarak kaldırmayı deneyebilirsiniz:

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

0

Benim durumumda, bu hata yalnızca istemcimin bilgisayarında programımın web hizmetiyle iletişim kurmasını engelleyen katı bir güvenlik duvarı ilkesi varsa ortaya çıkıyor.

Bu yüzden bulabildiğim tek çözüm hatayı yakalamak ve kullanıcıyı güvenlik duvarı ayarlarını manuel olarak değiştirme konusunda bilgilendirmektir.


-1

Web.config yaklaşımı, IntApp web hizmeti etkin kurallarına InfoPath form hizmetleri çağrıları için çalışır.

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

2
stackoverflow.com/a/7358457/11635 dup Bir nokta eklemek istiyorsanız lütfen yorum yapın
Ruben Bartelink
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.