{"id":119,"date":"2011-09-11T12:40:19","date_gmt":"2011-09-11T04:40:19","guid":{"rendered":"https:\/\/www.techcoil.com\/blog\/?p=119"},"modified":"2018-09-02T22:52:15","modified_gmt":"2018-09-02T14:52:15","slug":"uploading-large-http-multipart-request-with-system-net-httpwebrequest-in-c","status":"publish","type":"post","link":"https:\/\/www.techcoil.com\/blog\/uploading-large-http-multipart-request-with-system-net-httpwebrequest-in-c\/","title":{"rendered":"Uploading large HTTP multipart request with System.Net.HttpWebRequest in C#"},"content":{"rendered":"<p>My <a title=\"Sending a file and some form data via HTTP post in C#\" href=\"http:\/\/www.techcoil.com\/blog\/2011\/06\/11\/sending-a-file-and-some-form-data-via-http-post-in-c\/\" target=\"_blank\">previous post<\/a> described a method of sending a file and some data via HTTP multipart post by constructing the HTTP request with the <a title=\"MSDN reference for the System.IO.MemoryStream class\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.io.memorystream.aspx\" target=\"_blank\">System.IO.MemoryStream<\/a> class before writing the contents to the <a title=\"MSDN reference for the System.Net.HttpWebRequest class\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.net.httpwebrequest.aspx\" target=\"_blank\" title = \"MSDN reference for HttpWebRequest class\">System.Net.HttpWebRequest<\/a> class. This method of sending our HTTP request will work only if we can restrict the total size of our file and data. <\/p>\n<p>Although the MemoryStream class reduces programming effort, using it to hold a large amount of data will result in a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.outofmemoryexception.aspx\" target=\"_blank\" title=\"MSDN reference for the OutOfMemoryException class\">System.OutOfMemoryException<\/a> being thrown. Hence, to send large amount of data, we will need to write our contents to the HttpWebRequest instance directly. Before doing so, there are several properties in the HttpWebRequest instance that we will need to set.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nHttpWebRequest requestToServer = (HttpWebRequest)\r\n    WebRequest.Create(&quot;http:\/\/localhost\/fileReceiver.php&quot;);\r\n\r\n\/\/ Define a boundary string\r\nstring boundaryString = &quot;----SomeRandomText&quot;;\r\n\r\n\/\/ Turn off the buffering of data to be written, to prevent\r\n\/\/ OutOfMemoryException when sending data\r\nrequestToServer.AllowWriteStreamBuffering = false;\r\n\/\/ Specify that request is a HTTP post\r\nrequestToServer.Method = WebRequestMethods.Http.Post;\r\n\/\/ Specify that the content type is a multipart request\r\nrequestToServer.ContentType \r\n    = &quot;multipart\/form-data; boundary=&quot; + boundaryString;\r\n\/\/ Turn off keep alive\r\nrequestToServer.KeepAlive = false;\r\n<\/pre>\n<h2>Calculating the total size of the upload content<\/h2>\n<p>Recall that a HTTP multipart post request resembles the following form:<\/p>\n<pre><code>POST http:\/\/127.0.0.1\/GetPostRequest.php HTTP\/1.1\r\nHost: 127.0.0.1\r\nConnection: keep-alive\r\nReferer: http:\/\/localhost\/GetPostRequest.php\r\nContent-Length: 1611568\r\nCache-Control: max-age=0\r\nOrigin: http:\/\/localhost\r\nUser-Agent: Mozilla\/5.0 (Windows NT 6.1; WOW64) AppleWebKit\/534.30 (KHTML, like Gecko) Chrome\/12.0.742.91 Safari\/534.30\r\nContent-Type: multipart\/form-data; boundary=----WebKitFormBoundaryX6nBO7q27yQ1JNbb\r\nAccept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n\r\n------WebKitFormBoundaryX6nBO7q27yQ1JNbb\r\nContent-Disposition: form-data; name=\"myFileDescription\"\r\n\r\n My sample file description.\r\n------WebKitFormBoundaryX6nBO7q27yQ1JNbb\r\nContent-Disposition: form-data; name=\"myFile\"; filename=\"SomeRandomFile.pdf\"\r\nContent-Type: application\/pdf\r\n\r\nfile contents...\r\n------WebKitFormBoundaryX6nBO7q27yQ1JNbb--<\/code><\/pre>\n<p>From the HTTP request created by the browser, we see that the upload content spans from the first boundary string &nbsp;to the last boundary string. The total size of this block of content need to be set to the ContentLength property of the HttpWebRequest instance, <strong>before we write any data out to the request stream.<\/strong> To calculate the total size of the HTTP request, we need to add the byte sizes of the string values and the file that we are going to upload. We can convert the strings in the HTTP request into byte arrays with the <a title=\"MSDN reference for the ASCIIEncoding class\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.text.asciiencoding.aspx\" target=\"_blank\">System.Text.ASCIIEncoding<\/a> class and get the size of the strings with the Length property of the byte arrays. The size of the file can be retrieved via the <code>Length<\/code> property of a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.io.fileinfo.aspx\" target=\"_blank\" title=\"MSDN reference for the FileInfo class\">System.IO.FileInfo<\/a> instance.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nASCIIEncoding ascii = new ASCIIEncoding();\r\nstring boundaryStringLine = &quot;\\r\\n--&quot; + boundaryString + &quot;\\r\\n&quot;;\r\nbyte&#x5B;] boundaryStringLineBytes = ascii.GetBytes(boundaryStringLine);\r\n\r\nstring lastBoundaryStringLine = &quot;\\r\\n--&quot; + boundaryString + &quot;--\\r\\n&quot;;\r\nbyte&#x5B;] lastBoundaryStringLineBytes = ascii.GetBytes(lastBoundaryStringLine);\r\n\r\n\/\/ Get the byte array of the myFileDescription content disposition\r\nstring myFileDescriptionContentDisposition = String.Format(\r\n    &quot;Content-Disposition: form-data; name=\\&quot;{0}\\&quot;\\r\\n\\r\\n{1}&quot;,\r\n    &quot;myFileDescription&quot;,\r\n    &quot;A sample file description&quot;);\r\nbyte&#x5B;] myFileDescriptionContentDispositionBytes \r\n    = ascii.GetBytes(myFileDescriptionContentDisposition);\r\n\r\nstring fileUrl = @&quot;C:\\SomeRandomFile.pdf&quot;;\r\n\/\/ Get the byte array of the string part of the myFile content\r\n\/\/ disposition\r\nstring myFileContentDisposition = String.Format(\r\n    &quot;Content-Disposition: form-data;name=\\&quot;{0}\\&quot;; &quot;\r\n     + &quot;filename=\\&quot;{1}\\&quot;\\r\\nContent-Type: {2}\\r\\n\\r\\n&quot;,\r\n    &quot;myFile&quot;, Path.GetFileName(fileUrl), Path.GetExtension(fileUrl));\r\nbyte&#x5B;] myFileContentDispositionBytes =\r\n    ascii.GetBytes(myFileContentDisposition);\r\n\r\nFileInfo fileInfo = new FileInfo(fileUrl);\r\n\r\n\/\/ Calculate the total size of the HTTP request\r\nlong totalRequestBodySize = boundaryStringLineBytes.Length * 2\r\n    + lastBoundaryStringLineBytes.Length\r\n    + myFileDescriptionContentDispositionBytes.Length\r\n    + myFileContentDispositionBytes.Length\r\n    + fileInfo.Length;\r\n\/\/ And indicate the value as the HTTP request content length\r\nrequestToServer.ContentLength = totalRequestBodySize;\r\n<\/pre>\n<h2>Sending the HTTP request content<\/h2>\n<p>After calculating the content length, we can write the byte arrays that we have generated previously to the stream returned via the HttpWebRequest.GetRequestStream() method.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\/\/ Write the http request body directly to the server\r\nusing (Stream s = requestToServer.GetRequestStream())\r\n{\r\n    \/\/ Send the file description content disposition over to the server\r\n    s.Write(boundaryStringLineBytes, 0, boundaryStringLineBytes.Length);\r\n    s.Write(myFileDescriptionContentDisposition , 0,\r\n        myFileDescriptionContentDisposition.Length);\r\n\r\n    \/\/ Send the file content disposition over to the server\r\n    s.Write(boundaryStringLineBytes, 0, boundaryStringLineBytes.Length);\r\n    s.Write(myFileContentDispositionBytes, 0,\r\n        myFileContentDispositionBytes.Length);\r\n\r\n    \/\/ Send the file binaries over to the server, in 1024 bytes chunk\r\n    FileStream fileStream = new FileStream(fileUrl, FileMode.Open,\r\n        FileAccess.Read);\r\n    byte&#x5B;] buffer = new byte&#x5B;1024];\r\n    int bytesRead = 0;\r\n    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)\r\n    {\r\n        s.Write(buffer, 0, bytesRead);\r\n    } \/\/ end while\r\n    fileStream.Close();\r\n\r\n    \/\/ Send the last part of the HTTP request body\r\n    s.Write(lastBoundaryStringLineBytes, 0, lastBoundaryStringLineBytes.Length);\r\n} \/\/ end using\r\n<\/pre>\n<h2>Getting the response from the server<\/h2>\n<p>We get the server response by reading from the <a title=\"MSDN reference to System.Net.WebResponse class\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.net.webresponse.aspx\" target=\"_blank\">System.Net.WebResponse<\/a> instance, that can be retrieved via the <a title=\"MSDN reference to HttpWebRequest.GetResponseStream()\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.net.httpwebrequest.getresponse.aspx\" target=\"_blank\">HttpWebRequest.GetResponseStream()<\/a> method.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\/\/ Grab the response from the server. WebException will be thrown\r\n\/\/ when a HTTP OK status is not returned\r\nWebResponse response = requestToServer.GetResponse();\r\nStreamReader responseReader = new StreamReader(response.GetResponseStream());\r\nstring replyFromServer = responseReader.ReadToEnd();\r\n<\/pre>\n<h3>Related posts<\/h3>\n<ul>\n<li><a href=\"\/blog\/downloading-a-file-from-via-http-post-and-http-get-in-c\/\" target=\"_blank\">Downloading a file from a HTTP server with System.Net.HttpWebRequest in C#<\/a><\/li>\n<li><a href=\"\/blog\/handling-web-server-communication-feedback-with-system-net-webexception\/\" target=\"_blank\">Handling web server communication feedback with System.Net.WebException in C#<\/a><\/li>\n<li><a href=\"\/blog\/sending-a-file-and-some-form-data-via-http-post-in-c\/\" target=\"_blank\">Sending a file and some form data via HTTP post in C#<\/a><\/li>\n<li><a href=\"\/blog\/how-to-build-a-web-based-user-interaction-layer-in-c\/\" target=\"_blank\">How to build a web based user interaction layer in C#<\/li>\n<\/ul>\n\n      <ul id=\"social-sharing-buttons-list\">\n        <li class=\"facebook\">\n          <a href=\"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A%2F%2Fwp.me%2Fp245TQ-1V\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n            <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Facebook.png\" alt=\"Facebook icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"twitter\">\n          <a href=\"https:\/\/twitter.com\/intent\/tweet?text=&url=https%3A%2F%2Fwp.me%2Fp245TQ-1V&via=Techcoil_com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Twitter.png\" alt=\"Twitter icon\"> Tweet\n          <\/a>\n        <\/li>\n        <li class=\"linkedin\">\n          <a href=\"https:\/\/www.linkedin.com\/shareArticle?mini=1&title=&url=https%3A%2F%2Fwp.me%2Fp245TQ-1V&source=https:\/\/www.techcoil.com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/linkedin.png\" alt=\"Linkedin icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"pinterest\">\n          <a href=\"https:\/\/pinterest.com\/pin\/create\/button\/?url=https%3A%2F%2Fwww.techcoil.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F119&description=\" class=\"pin-it-button\" target=\"_blank\" role=\"button\" rel=\"nofollow\" count-layout=\"horizontal\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Pinterest.png\" alt=\"Pinterest icon\"> Save\n          <\/a>\n        <\/li>\n      <\/ul>\n    ","protected":false},"excerpt":{"rendered":"<p>My <a title=\"Sending a file and some form data via HTTP post in C#\" href=\"http:\/\/www.techcoil.com\/blog\/2011\/06\/11\/sending-a-file-and-some-form-data-via-http-post-in-c\/\" target=\"_blank\">previous post<\/a> described a method of sending a file and some data via HTTP multipart post by constructing the HTTP request with the <a title=\"MSDN reference for the System.IO.MemoryStream class\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.io.memorystream.aspx\" target=\"_blank\">System.IO.MemoryStream<\/a> class before writing the contents to the <a title=\"MSDN reference for the System.Net.HttpWebRequest class\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.net.httpwebrequest.aspx\" target=\"_blank\" title = \"MSDN reference for HttpWebRequest class\">System.Net.HttpWebRequest<\/a> class. This method of sending our HTTP request will work only if we can restrict the total size of our file and data.<\/p>\n","protected":false},"author":1,"featured_media":1189,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"footnotes":""},"categories":[375],"tags":[20,23,34,161,51],"jetpack_featured_media_url":"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/C-Sharp-Logo.gif","jetpack_shortlink":"https:\/\/wp.me\/p245TQ-1V","jetpack-related-posts":[],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/119"}],"collection":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/comments?post=119"}],"version-history":[{"count":0,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/119\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media\/1189"}],"wp:attachment":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media?parent=119"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/categories?post=119"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/tags?post=119"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}