Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to Create Asynchronous HttpWebRequest in Silverlight( F#)
    primarykey
    data
    text
    <p>As I mentioned, because <a href="https://stackoverflow.com/questions/3054631/silverlight-httpwebrequest-create-hangs-inside-async-block">Silverlight HttpWebRequest.Create hangs inside async block</a>, I just created a bundle of callback functions to implement the same async block. </p> <p>The login process requires two steps :</p> <p>1) Get request to a page that returns a cookie 2) Form Post to a second page that passes that cookie w/ it and performs the authentication</p> <p>The following is the src. Any suggestions and discussions are welcome and appreciated no matter about Asynchronous HttpWebRequest or about the F# code style. </p> <pre><code>module File1 open System open System.IO open System.Net open System.Text open System.Security open System.Runtime.Serialization open System.Collections.Generic open JsonData open System.Net.Browser open System.Threading module rpc = let mutable BASE_DNS = "" let mutable requestId : int = 0 let getId() = requestId &lt;- requestId + 1 requestId.ToString() module internal Helper = ///&lt;Summary&gt; ///Transfer data from Security.loginToRpc to Helper.FetchCookieCallback ///&lt;/Summary&gt; type LoginRequestRecord = { Request : HttpWebRequest; UserName : string; Password : string; AuthenticationUrl : string; CallbackUI : (bool -&gt; unit) } ///&lt;Summary&gt; ///Transfer data from Helper.FetchCookieCallback to Helper.requestAuthenticationCallback ///&lt;/Summary&gt; type AuthenticationRecord = { Request : HttpWebRequest; UserName : string; Password : string; CallbackUI : (bool -&gt; unit) } ///&lt;Summary&gt; ///Transfer data from Helper.requestAuthenticationCallback to Helper.responseAuthenticationCallback ///&lt;/Summary&gt; type ResponseAuthenticationRecord = { Request : HttpWebRequest; CallbackUI : (bool -&gt; unit) } ///&lt;Summary&gt; ///The cookieContainer for all the requests in the session ///&lt;/Summary&gt; let mutable cookieJar = new CookieContainer() ///&lt;summary&gt; ///Function: Create HttpRequest ///Param: string ///Return: HttpWebRequest ///&lt;/summary&gt; let internal createHttpRequest (queryUrl : string) = let uri = new Uri(queryUrl) let request : HttpWebRequest = downcast WebRequestCreator.ClientHttp.Create( new Uri(queryUrl, UriKind.Absolute)) request ///&lt;summary&gt; ///Function: set request whose method is "GET". ///Attention: no contentType for "GET" request~!!!!!!!!!!!!!!!! ///Param: HttpWebRequest ///Return: unit ///&lt;/summary&gt; let internal requestGetSet (request : HttpWebRequest) = request.Method &lt;- "GET" ///&lt;summary&gt; ///Function: set request whose method is "POST" and its contentType ///Param: HttpWebRequest and contentType string ///Return: unit ///&lt;/summary&gt; let internal requestPostSet (request : HttpWebRequest) contentType = request.Method &lt;- "POST" request.ContentType &lt;- contentType ///&lt;summary&gt; ///Function: Callback function inluding EndGetResponse method of request ///Param: IAsyncResult includes the information of HttpWebRequest ///Return: unit ///&lt;/summary&gt; let internal responseAuthenticationCallback (ar : IAsyncResult) = let responseAuthentication : ResponseAuthenticationRecord = downcast ar.AsyncState try let response = responseAuthentication.Request.EndGetResponse(ar) //check whether the authentication is successful, //which may be changed later into other methods match response.ContentLength with | -1L -&gt; responseAuthentication.CallbackUI true | _ -&gt; responseAuthentication.CallbackUI false () with | Ex -&gt; responseAuthentication.CallbackUI false ///&lt;summary&gt; ///Function: Callback function for user to log into the website ///Param: IAsyncResult includes the information of ///HttpWebRequest and user's identity ///Return: unit ///&lt;/summary&gt; let internal requestAuthenticationCallback (ar : IAsyncResult) = let authentication : AuthenticationRecord = downcast ar.AsyncState try let requestStream = authentication.Request.EndGetRequestStream(ar) let streamWriter = new StreamWriter(requestStream) streamWriter.Write( String.Format( "j_username={0}&amp;j_password={1}&amp;login={2}", authentication.UserName, authentication.Password, "Login")) streamWriter.Close() let responseAuthentication = { ResponseAuthenticationRecord.Request = authentication.Request ResponseAuthenticationRecord.CallbackUI = authentication.CallbackUI } authentication.Request.BeginGetResponse( new AsyncCallback(responseAuthenticationCallback), responseAuthentication) |&gt; ignore with | Ex -&gt; authentication.CallbackUI false () ///&lt;summary&gt; ///This is a magic number to check ///whether the first request have got the cookie from the server-side, ///which should be changed later ///&lt;/summary&gt; let countHeadersAfterGetCookie = 8 ///&lt;summary&gt; ///Function: Callback function to get the cookie and ///Param: IAsyncResult includes the information of ///login request, username, password and callbackUI ///Return: ///&lt;/summary&gt; let internal FetchCookieCallback (ar : IAsyncResult) = let loginRequest : LoginRequestRecord = downcast ar.AsyncState try let response = loginRequest.Request.EndGetResponse(ar) let request : HttpWebRequest = createHttpRequest loginRequest.AuthenticationUrl requestPostSet request "application/x-www-form-urlencoded" request.CookieContainer &lt;- cookieJar //if the cookie is got, call the callback function; or else, return to UI match response.Headers.Count with | countHeadersAfterGetCookie -&gt; let authentication = { AuthenticationRecord.Request = request; AuthenticationRecord.UserName = loginRequest.UserName; AuthenticationRecord.Password = loginRequest.Password; AuthenticationRecord.CallbackUI = loginRequest.CallbackUI } request.BeginGetRequestStream( new AsyncCallback(requestAuthenticationCallback), authentication) |&gt; ignore () | _ -&gt; loginRequest.CallbackUI false () with | Ex -&gt; loginRequest.CallbackUI false module Security = ///&lt;summary&gt; ///Function: Use the async workflow around 2 we calls: /// 1. get the cookie; 2. log into the website ///Param: UserName and password ///Return: unit ///&lt;/summary&gt; let loginToRpc (userName : string) (password : string) (callbackUI : (bool-&gt; unit)) = let sessionIdUrl = BASE_DNS let authenticationUrl = BASE_DNS + "..................." let request : HttpWebRequest = Helper.createHttpRequest sessionIdUrl Helper.requestGetSet(request) request.CookieContainer &lt;- Helper.cookieJar let loginRequest = { Helper.LoginRequestRecord.Request = request Helper.LoginRequestRecord.UserName = userName Helper.LoginRequestRecord.Password = password Helper.LoginRequestRecord.AuthenticationUrl = authenticationUrl Helper.LoginRequestRecord.CallbackUI = callbackUI } request.BeginGetResponse(new AsyncCallback(Helper.FetchCookieCallback), loginRequest) |&gt; ignore () </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload