Created
June 1, 2011 15:11
-
-
Save michaelbartnett/1002498 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.Windows; | |
using System.Windows.Controls; | |
using System.Windows.Documents; | |
using System.Windows.Ink; | |
using System.Windows.Input; | |
using System.Windows.Media; | |
using System.Windows.Media.Animation; | |
using System.Windows.Shapes; | |
using System.IO; | |
using System.Text; | |
using System.Net.Browser; | |
namespace RESTUtil | |
{ | |
public delegate void RESTTransactionCompletedHandler(object sender, RESTTransactionCompletedArgs args); | |
public class RESTWebClient | |
{ | |
private const int BUFFERSIZE = 1024; | |
private HttpWebRequest uploadStringRequest; // Request object to do the actual sending | |
private string uploadStringData; // Data to be sent | |
// Buffers for Stream.BeginRead() | |
private byte[] uploadStringReadbuffer; | |
private StringBuilder uploadStringReadResult; | |
// Properties for polling status after transaction completes | |
public bool CurrentTransActionComplete { get; private set; } | |
public WebHeaderCollection ResponseHeaders { get; private set; } | |
public HttpStatusCode ResponseStatusCode { get; private set; } | |
public string ResponseStatusDescription { get; private set; } | |
public string CurrentResponseString | |
{ | |
get | |
{ | |
if (uploadStringReadResult != null) { | |
return uploadStringReadResult.ToString(); | |
} else { | |
return string.Empty; | |
} | |
} | |
} | |
// Fire when transaction is completed (byteRead == 0) | |
public event RESTTransactionCompletedHandler UploadStringCompleted; | |
// Slightly mimics WebClient api | |
public void UploadStringAsync(Uri address, string method, string data) | |
{ | |
// Initialize buffers | |
uploadStringReadbuffer = new byte[BUFFERSIZE]; | |
uploadStringReadResult = new StringBuilder(); | |
// Enable the Client http stack | |
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp); | |
WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp); | |
// Create HttpWebRequest via WebRequestCreator.ClientHttp (implied because of RegisterPrefix) | |
uploadStringRequest = WebRequest.Create(address) as HttpWebRequest; | |
// Prepare request | |
uploadStringRequest.Method = method; | |
uploadStringData = data; | |
// Get stream to write to | |
uploadStringRequest.BeginGetRequestStream(UploadStringWrite, null); | |
} | |
private void UploadStringWrite(IAsyncResult iar) | |
{ | |
// Get stream to write data to | |
Stream s = uploadStringRequest.EndGetRequestStream(iar); | |
StreamWriter sw = new StreamWriter(s); | |
// Write data | |
sw.Write(uploadStringData); | |
sw.Close(); | |
// Get response async | |
uploadStringRequest.BeginGetResponse(UploadStringRead, null); | |
} | |
private void UploadStringRead(IAsyncResult iar) | |
{ | |
HttpWebResponse response = null; | |
try { | |
// **************PUT requests fail after this line************** | |
response = uploadStringRequest.EndGetResponse(iar) as HttpWebResponse; | |
} catch (WebException we) { | |
response = we.Response as HttpWebResponse; | |
} catch (Exception e) { | |
System.Diagnostics.Debug.WriteLine(e); | |
} | |
// Set status properties so they can be checked later | |
ResponseHeaders = response.Headers; | |
ResponseStatusCode = response.StatusCode; | |
ResponseStatusDescription = response.StatusDescription; | |
// Get the response stream to read async | |
var stream = response.GetResponseStream(); | |
var reader = new StreamReader(stream); | |
// Begin reading asynchronously ("driver" call to recursive read method) | |
stream.BeginRead(uploadStringReadbuffer, 0, BUFFERSIZE, UploadStringStreamCallback, stream); | |
} | |
private void UploadStringStreamCallback(IAsyncResult result) | |
{ | |
// User state is always the Stream object | |
var stream = result.AsyncState as Stream; | |
// Read bytes, decode into string with UTF8, append to StringBuilder so we can reuse the byte buffer | |
var bytesRead = stream.EndRead(result); | |
uploadStringReadResult.Append(Encoding.UTF8.GetString(uploadStringReadbuffer, 0, bytesRead)); | |
// If we read bytes, try to read again, otherwise we've reached the end of the stream | |
if (bytesRead > 0) { | |
stream.BeginRead(uploadStringReadbuffer, 0, BUFFERSIZE, UploadStringStreamCallback, stream); | |
} else { | |
// If we're done, invoke the callback | |
if (UploadStringCompleted != null) { | |
UploadStringCompleted.Invoke(this, new RESTTransactionCompletedArgs(uploadStringReadResult.ToString(), true)); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment