{"id":3278,"date":"2015-12-20T18:58:11","date_gmt":"2015-12-20T17:58:11","guid":{"rendered":"https:\/\/u-labs.de\/?p=3278"},"modified":"2015-12-20T18:58:11","modified_gmt":"2015-12-20T17:58:11","slug":"net-sie-muessen-contentlength-byte-fuer-den-anforderungsstream-schreiben-bevor-sie-begingetresponse-aufrufen","status":"publish","type":"post","link":"https:\/\/u-labs.de\/portal\/net-sie-muessen-contentlength-byte-fuer-den-anforderungsstream-schreiben-bevor-sie-begingetresponse-aufrufen\/","title":{"rendered":".NET: Sie m\u00fcssen ContentLength-Byte f\u00fcr den Anforderungsstream schreiben, bevor Sie [Begin]GetResponse aufrufen"},"content":{"rendered":"<p>Ein formell richtiger Http-Request, der beispielsweise \u00fcber die HttpWebRequest-Klasse von .NET erzeugt wird, wirft die Exception<\/p>\n<blockquote><p>.NET: Sie m\u00fcssen ContentLength-Byte f\u00fcr den Anforderungsstream schreiben, bevor Sie [Begin]GetResponse aufrufen<\/p><\/blockquote>\n<p>Schaut man sich den Code an, \u00a0wird\u00a0die Content-Length Eigenschaft und somit auch der dazugeh\u00f6rige Header korrekt gesetzt &#8211; Dementsprechend erscheint die Fehlermeldung recht verwirrend. Beim genaueren Betrachten wird jedoch ein Denkfehler des Entwicklers sichtbar. Zur Verdeutlichung des Problemes ein simples Beispiel:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n        public void SendRequest(string requestUrl, string body) {\r\n            var request = (HttpWebRequest)WebRequest.Create(requestUrl);\r\n            request.ContentType = &quot;application\/x-www-form-urlencoded&quot;;\r\n            request.ContentLength = body.Length;\r\n            var bodyAsBytes = Encoding.UTF8.GetBytes(body);\r\n            request.GetRequestStream().Write(bodyAsBytes, 0, bodyAsBytes.Length);\r\n        }\r\n<\/pre>\n<p>Die Variable <strong>body<\/strong> wird ein String wie beispielsweise <strong>username=Peter&amp;password=123<\/strong> sein. Nat\u00fcrlich lie\u00dfe sich dieses umst\u00e4ndliche zusammenbasteln deutlich vereinfachen, in dem etwa ein Dictionary \u00fcbergeben und sp\u00e4ter entsprechend aufbereitet wird.\u00a0Um den Fokus auf das wesentliche zu setzen, habe ich diese Helfer an dieser Stelle bewusst entfernt. Das Problem ist n\u00e4mlich, dass die L\u00e4nge des\u00a0<strong>Strings<\/strong>\u00a0gesetzt wird. In den Anforderungsstream wird\u00a0der Body jedoch als UTF8-Kodiertes Byte-Array geschrieben. Die L\u00e4nge dieser beiden Varianten kann sich unterscheiden, obwohl die gleichen Daten enthalten sind. In diesem Fall erwartet der Server anhand des\u00a0<strong>ContentLength-Headers<\/strong>\u00a0mehr oder weniger Daten, als er tats\u00e4chlich erh\u00e4lt.<\/p>\n<p>Korrekterweise m\u00fcssten wir daher die L\u00e4nge des Byte-Arrays\u00a0<strong>bodyAsBytes<\/strong> verwenden:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar bodyAsBytes = Encoding.UTF8.GetBytes(body);\r\nrequest.ContentLength = bodyAsBytes.Length;\r\n<\/pre>\n<p>Dies ist allerdings an dieser Stelle gar nicht notwendig: Das .NET Framework ist intelligent genug, die L\u00e4nge des RequestStreams automatisch vor dem Absenden als <strong>Content-Length<\/strong> Header zu setzen. Somit kann dieser Aufruf komplett wegfallen, und die obige Beispielmethode l\u00e4sst sich folgenderma\u00dfen reduzieren:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n        public void SendRequest(string requestUrl, string body) {\r\n            var request = (HttpWebRequest)WebRequest.Create(requestUrl);\r\n            request.ContentType = &quot;application\/x-www-form-urlencoded&quot;;\r\n            var bodyAsBytes = Encoding.UTF8.GetBytes(body);\r\n            request.GetRequestStream().Write(bodyAsBytes, 0, bodyAsBytes.Length);\r\n        }\r\n<\/pre>\n<p>Die\u00a0Fehlerquelle welche zur urspr\u00fcnglichen Exception gef\u00fchrt hat, haben wir damit ebenfalls umgangen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ein formell richtiger Http-Request, der beispielsweise \u00fcber die HttpWebRequest-Klasse von .NET erzeugt wird, wirft die Exception .NET: Sie m\u00fcssen ContentLength-Byte f\u00fcr den Anforderungsstream schreiben, bevor Sie [Begin]GetResponse aufrufen Schaut man sich den Code an, \u00a0wird\u00a0die Content-Length Eigenschaft und somit auch der dazugeh\u00f6rige Header korrekt gesetzt &#8211; Dementsprechend erscheint die Fehlermeldung recht verwirrend. Beim genaueren Betrachten &#8230;<\/p>\n","protected":false},"author":5,"featured_media":3285,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[61],"tags":[331,330,332,333,335,334],"class_list":["post-3278","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-softwareentwicklung","tag-net","tag-c","tag-content-length","tag-exception","tag-http","tag-webrequest"],"_links":{"self":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/3278","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/comments?post=3278"}],"version-history":[{"count":5,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/3278\/revisions"}],"predecessor-version":[{"id":3286,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/3278\/revisions\/3286"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media\/3285"}],"wp:attachment":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media?parent=3278"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/categories?post=3278"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/tags?post=3278"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}