Ok, so you want to do an asynchronous POST and pass in the data to your post method. But, the asynchronous callback only allows you to return one parameter. No problem...just wrap it.
- Create a tuple class to hold whatever data that you want to send through to the callback. You can put as many items in here as you would like.
- Pass the tuple in as your object state in the BeginGetRequestStream method.
- At the callback, break apart the tuple to your original items
/// <summary>
/// Asynchonously post data to some url
/// </summary>
/// <param name="url">The URL of the feed to POST to</param>
/// <param name="data">The data to post</param>
private void PostData(string url, PostData data)
{
try
{
//Post the the data to the feed service
Uri uri = new Uri(url);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "POST";
//Create a tuple so that we can access the data and
//the web request in the request callback
MyTuple tuple = new MyTuple(request, data);
//pass the tuple in as the object, we get can break it apart at the request callback
request.BeginGetRequestStream(new AsyncCallback(RequestCallback), tuple);
}
catch (Exception ex)
{
//write any errors to the system event log
}
}
/// <summary>
/// The request callback for the POST Data method
/// </summary>
/// <param name="ar">The async result from the POST data method. This result contains
/// the data to be be POSTed and the HTTP WebRequest. Both items are wrapped in a Tuple object
/// since only one item is allowed to be passed in</param>
private void RequestCallback(IAsyncResult ar)
{
try
{
//get back the tuple because it holds the data to send and the HttpRequest
MyTuple tuple = ar.AsyncState as MyTuple;
if (tuple != null)
{
//Get the Http request
HttpWebRequest request = tuple.MyHttpWebRequest;
request.ContentType = "text/xml";
Stream requestStream = request.EndGetRequestStream(ar);
StreamWriter streamWriter = new StreamWriter(requestStream);
//create serializer so we can serialize the POST data as XML
XmlSerializer serializer = new XmlSerializer(typeof(PostData));
//serialize the POST data so we can send it out
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
serializer.Serialize(sw, tuple.MyPostData);
}
string xmlContent = sb.ToString();
xmlContent = xmlContent.Replace(@"encoding=""utf-16""", @"encoding=""utf-8"""); //change the encoding to utf-8
streamWriter.Write(xmlContent); //send the xml content
streamWriter.Close();
//start the response
request.BeginGetResponse(new AsyncCallback(ResponseCallback), request);
}
}
catch (Exception ex)
{
//write any errors to the system event log
}
}
/// <summary>
/// The Response callback.
/// Gets called when it returns from BeginGetResponse() in the
/// RequestCallback method.
/// </summary>
/// <param name="asynchronousResult"></param>
private void ResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
if (request.HaveResponse)
{
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
using (StreamReader streamReader1 = new StreamReader(response.GetResponseStream()))
{
string resultString = streamReader1.ReadToEnd();
}
}
}
catch (Exception ex)
{
//write any errors to the system event log
}
}
}
/// <summary>
/// A Tuple to hold the webrequest and the data to post. Since we can only pass
/// one thing in as an ISyncResult, use this to wrap the data that
/// we want to send with the HttpWebrequest
/// </summary>
public class MyTuple
{
HttpWebRequest _webRequest = null;
PostData _postData = null;
public MyTuple(HttpWebRequest asyncResult, PostData data)
{
_webRequest = asyncResult;
_postData = data;
}
public HttpWebRequest MyHttpWebRequest { get { return _webRequest; } }
public PostData MyPostData { get { return _postData; } }
}
/// <summary>
/// The data to be POSTed
/// </summary>
public class PostData
{
string Name { get; set; }
string Address { get; set; }
}
No comments:
Post a Comment