{"id":22,"date":"2010-04-19T21:54:28","date_gmt":"2010-04-19T20:54:28","guid":{"rendered":"http:\/\/ree7.fr\/blog\/?p=22"},"modified":"2014-10-07T08:45:12","modified_gmt":"2014-10-07T07:45:12","slug":"ready-made-usual-flavour-httpwebrequest-for-windows-phone-7","status":"publish","type":"post","link":"http:\/\/www.ree7.fr\/blog\/2010\/04\/ready-made-usual-flavour-httpwebrequest-for-windows-phone-7\/","title":{"rendered":"Ready-made usual flavour HttpWebRequest for Windows Phone 7"},"content":{"rendered":"<p>Si vous effectuez des portages d&rsquo;applications .NET vers Silverlight ou Windows Phone 7, cette classe pourrait bien vous \u00eatre utile.<br \/>\nEn effet, dans Silverlight, les WebRequests sont asynchrones (c&rsquo;est tr\u00e8s bien !), seulement ce changement d&rsquo;API peut causer de nombreuses modifications de code. C&rsquo;est dans cette optique que j&rsquo;ai cr\u00e9e cette classe C# : HttpWebRequestSync qui propose une interface au plus proche de ce qui existait avant.<\/p>\n<p>Attention, pour le coup vous perdrez l&rsquo;avantage des requ\u00eates asynchrones et votre thread appelant sera bloqu\u00e9 pendant le d\u00e9roulement de la requ\u00eate, comme au bon vieux temps !<br \/>\nTout retour de bug ou message de remerciement est le bienvenu, ce code est disponible sous licence LGPL.<\/p>\n<p><em>If you&rsquo;re looking forward to port .NET applications to Silverlight\/Windows Phone 7, the following might interest you.<br \/>\nIn Silverlight, the WebRequests are asynchronous (and that&rsquo;s a good thing), but this change in the API can cause numerous changes in your code. That&rsquo;s what lead me to write this C# class : HttpWebRequestSync featuring an interface as close as possible as what was there before.<\/em><\/p>\n<p><em>Note that you&rsquo;ll lose the advantage of asynchronous requests and that you&rsquo;re thread will be locked waiting for the request to complete, ol&rsquo;school style.<br \/>\nIf you find any bug or just want to leave a &lsquo;thank you&rsquo; not you&rsquo;re welcome. This code is available under the LGPL license.<\/em><\/p>\n<p><!--more--><\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\/**********************************************************\r\n * HttpWebRequestSync.cs\r\n * Provides an implementation close to the .NET CF (3.5)\r\n * synchronous HttpWebRequest with Windows Phone 7's\r\n * asynchronous implementation.\r\n * TL;DR : Abstract the dev from all the async callback.\r\n *\r\n * Written by : Pierre BELIN &lt;pierre.belin@inbox.com&gt;\r\n *\r\n * This program is free software: you can redistribute it and\/or modify\r\n * it under the terms of the Lesser GNU General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\u00a0 See the\r\n * GNU General Public License for more details.\r\n *\r\n * You should have received a copy of the Lesser GNU General Public License\r\n * along with this program.\u00a0 If not, see &lt;http:\/\/www.gnu.org\/licenses\/&gt;.\r\n *\r\n **********************************************************\/\r\nusing System;\r\nusing System.Net;\r\nusing System.Threading;\r\nusing System.IO;\r\n\r\nnamespace Ree7.Utils.Net\r\n{\r\n public class HttpWebRequestSync\r\n {\r\n private ManualResetEvent getRequestDone = new ManualResetEvent(false);\r\n private ManualResetEvent getResponseDone = new ManualResetEvent(false);\r\n private HttpWebRequest request;\r\n\r\n private HttpWebResponse response;\r\n private Stream requestStream;\r\n\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Private ctor, to get an HttpWebRequestSync you shall use Create()\r\n \/\/\/ &lt;\/summary&gt;\r\n private HttpWebRequestSync()\r\n {\r\n\r\n }\r\n\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Initializes a new HttpWebRequestSync for the specified URI scheme\r\n \/\/\/ &lt;\/summary&gt;\r\n public static HttpWebRequestSync Create(string url)\r\n {\r\n return Create(new Uri(url));\r\n }\r\n\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Initializes a new HttpWebRequestSync for the specified URI scheme\r\n \/\/\/ &lt;\/summary&gt;\r\n public static HttpWebRequestSync Create(Uri uri)\r\n {\r\n HttpWebRequestSync wrs = new HttpWebRequestSync();\r\n wrs.request = (HttpWebRequest)WebRequest.Create(uri);\r\n\r\n return wrs;\r\n }\r\n\r\n #region HttpWebRequest Interface\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Summary:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 Gets or sets the value of the Accept HTTP header.\r\n \/\/\/\r\n \/\/\/ Returns:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 The value of the Accept HTTP header. The default value is null.\r\n \/\/\/ &lt;\/summary&gt;\r\n public string Accept\r\n {\r\n get\r\n {\r\n return request.Accept;\r\n }\r\n set\r\n {\r\n request.Accept = value;\r\n }\r\n }\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Not Implemented Yet\r\n \/\/\/ &lt;\/summary&gt;\r\n public int ContentLength\r\n {\r\n get\r\n {\r\n return 0;\r\n }\r\n set\r\n {\r\n return;\r\n }\r\n }\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Summary:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 Gets or sets the value of the Content-type HTTP header.\r\n \/\/\/\r\n \/\/\/ Returns:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 The value of the Content-type HTTP header. The default value is null.\r\n \/\/\/ &lt;\/summary&gt;\r\n public string ContentType\r\n {\r\n get\r\n {\r\n return request.ContentType;\r\n }\r\n set\r\n {\r\n request.ContentType = value;\r\n }\r\n }\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Summary:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 Specifies the collection of System.Net.CookieCollection objects associated\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 with the HTTP request.\r\n \/\/\/\r\n \/\/\/ Returns:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 A System.Net.CookieContainer that contains a collection of System.Net.CookieCollection\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 objects associated with the HTTP request.\r\n \/\/\/\r\n \/\/\/ Exceptions:\r\n \/\/\/\u00a0\u00a0 System.NotImplementedException:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 This property is not implemented.\r\n \/\/\/ &lt;\/summary&gt;\r\n public CookieContainer CookieContainer\r\n {\r\n get\r\n {\r\n return request.CookieContainer;\r\n }\r\n set\r\n {\r\n request.CookieContainer = value;\r\n }\r\n }\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Summary:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 Gets a value that indicates whether a response has been received from an\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 Internet resource.\r\n \/\/\/\r\n \/\/\/ Returns:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 true if a response has been received; otherwise, false.\r\n \/\/\/\r\n \/\/\/ Exceptions:\r\n \/\/\/\u00a0\u00a0 System.NotImplementedException:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 This property is not implemented.\r\n \/\/\/ &lt;\/summary&gt;\r\n public bool HaveResponse\r\n {\r\n get\r\n {\r\n return request.HaveResponse;\r\n }\r\n }\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Returns the underlying HttpWebRequest (handle it with care)\r\n \/\/\/ &lt;\/summary&gt;\r\n public HttpWebRequest HttpWebRequest\r\n {\r\n get\r\n {\r\n return request;\r\n }\r\n }\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Summary:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 Specifies a collection of the name\/value pairs that make up the HTTP headers.\r\n \/\/\/\r\n \/\/\/ Returns:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 A System.Net.WebHeaderCollection that contains the name\/value pairs that\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 make up the headers for the HTTP request.\r\n \/\/\/\r\n \/\/\/ Exceptions:\r\n \/\/\/\u00a0\u00a0 System.InvalidOperationException:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 The request has been started by calling the System.Net.HttpWebRequest.BeginGetRequestStream\r\n\r\n(System.AsyncCallback,System.Object)\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 or System.Net.HttpWebRequest.BeginGetResponse(System.AsyncCallback,System.Object)\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 method.\r\n \/\/\/ &lt;\/summary&gt;\r\n public WebHeaderCollection Headers\r\n {\r\n get\r\n {\r\n return request.Headers;\r\n }\r\n set\r\n {\r\n request.Headers = value;\r\n }\r\n }\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Summary:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 Gets or sets the method for the request.\r\n \/\/\/\r\n \/\/\/ Returns:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 The request method to use to contact the Internet resource. The default value\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 is GET.\r\n \/\/\/\r\n \/\/\/ Exceptions:\r\n \/\/\/\u00a0\u00a0 System.ArgumentException:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 No method is supplied.-or- The method string contains invalid characters.\r\n \/\/\/\r\n \/\/\/\u00a0\u00a0 System.NotImplementedException:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 This property is not implemented.\r\n \/\/\/\r\n \/\/\/\u00a0\u00a0 System.NotSupportedException:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 The System.Net.HttpWebRequest.Method property is not GET or POST.\r\n \/\/\/ &lt;\/summary&gt;\r\n public string Method\r\n {\r\n get\r\n {\r\n return request.Method;\r\n }\r\n set\r\n {\r\n request.Method = value;\r\n }\r\n }\r\n \/\/\/ &lt;summary&gt;\r\n \/\/\/ Summary:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 Gets the original Uniform Resource Identifier (URI) of the request.\r\n \/\/\/\r\n \/\/\/ Returns:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 A System.Uri that contains the URI of the Internet resource passed to the\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 System.Net.WebRequest.Create(System.Uri) method.\r\n \/\/\/\r\n \/\/\/ Exceptions:\r\n \/\/\/\u00a0\u00a0 System.NotImplementedException:\r\n \/\/\/\u00a0\u00a0\u00a0\u00a0 This property is not implemented.\r\n \/\/\/ &lt;\/summary&gt;\r\n public Uri RequestUri\r\n {\r\n get\r\n {\r\n return request.RequestUri;\r\n }\r\n }\r\n #endregion\r\n\r\n public Stream GetRequestStream()\r\n {\r\n \/\/ start the asynchronous operation\r\n request.AllowReadStreamBuffering = false;\r\n request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);\r\n\r\n \/\/ Keep the main thread from continuing while the asynchronous\r\n \/\/ operation completes. A real world application\r\n \/\/ could do something useful such as updating its user interface.\r\n getRequestDone.WaitOne();\r\n\r\n Stream result = requestStream;\r\n\r\n \/\/ Avoid keeping an unnecessary ref on the stream in this object\r\n requestStream = null;\r\n\r\n return result;\r\n }\r\n\r\n private void GetRequestStreamCallback(IAsyncResult asynchronousResult)\r\n {\r\n request = (HttpWebRequest)asynchronousResult.AsyncState;\r\n requestStream = request.EndGetRequestStream(asynchronousResult);\r\n\r\n getRequestDone.Set();\r\n }\r\n\r\n public HttpWebResponse GetResponse()\r\n {\r\n \/\/ Start the asynchronous operation to get the response\r\n request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);\r\n\r\n getResponseDone.WaitOne();\r\n\r\n HttpWebResponse result = response;\r\n\r\n \/\/ Avoid keeping an unnecessary ref on the response in this object\r\n response = null;\r\n\r\n return result;\r\n }\r\n\r\n private void GetResponseCallback(IAsyncResult asynchronousResult)\r\n {\r\n request = (HttpWebRequest)asynchronousResult.AsyncState;\r\n\r\n \/\/ End the operation\r\n response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);\r\n\r\n getResponseDone.Set();\r\n }\r\n\r\n }\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Si vous effectuez des portages d&rsquo;applications .NET vers Silverlight ou Windows Phone 7, cette classe pourrait bien vous \u00eatre utile. En effet, dans Silverlight, les WebRequests sont asynchrones (c&rsquo;est tr\u00e8s bien !), seulement ce changement d&rsquo;API peut causer de nombreuses modifications de code. C&rsquo;est dans cette optique que j&rsquo;ai cr\u00e9e cette classe C# : HttpWebRequestSync [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[18],"tags":[52,22,21,19,20],"jetpack_publicize_connections":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p19lzH-m","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/www.ree7.fr\/blog\/wp-json\/wp\/v2\/posts\/22"}],"collection":[{"href":"http:\/\/www.ree7.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.ree7.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.ree7.fr\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.ree7.fr\/blog\/wp-json\/wp\/v2\/comments?post=22"}],"version-history":[{"count":0,"href":"http:\/\/www.ree7.fr\/blog\/wp-json\/wp\/v2\/posts\/22\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.ree7.fr\/blog\/wp-json\/wp\/v2\/media?parent=22"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.ree7.fr\/blog\/wp-json\/wp\/v2\/categories?post=22"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.ree7.fr\/blog\/wp-json\/wp\/v2\/tags?post=22"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}