I just started using C# so forgive my ignorance(if any) of how i use it. I have a login button which executes the following code
private void Login_Click(object sender, RoutedEventArgs e)
{
if (email_box.Text != "" && password_box.Password != "") {
string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" + @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" + @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
Regex reg = new Regex(strRegex);
if (reg.IsMatch(email_box.Text))
{
ApiCall request = new ApiCall();
request.requestData = "{\"sessions\": {\"links\":{\"user\":{\"email\":\"" + email_box.Text + "\",\"password\":\"" + password_box.Password + "\" }}}}";
request.requestMethod = Constants.httpMethods[0];
request.resource_url = "/sessions";
var response = request.initialize_request();
//Once i get the response string, i will deserialize it here and use it to do other things, like navigate to a new page an any other neccessary things to do!
}
else
{
recover.Text = "Please provide a valid email address.";
}
}
else
{
recover.Text = "Email and Password cannot be Empty";
}
}
The method initializese this class and also calls the initialize_request() , which inturn calls the GetRequestStreamCallback which also calls the GetResponseStreamCallback .
Intialize request is supposed to send back a string, which is set in GetResponseStreamCallBack but it seems, it sends back a string before the last two methods have executed. Soo, i read about async and await and i have tried to use them, but the Visual Studio says Cannot await "method group" where i put the awaits
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
using System.Net;
using Newtonsoft.Json;
using PrintMyPic.ApiJsonObjects;
using PrintMyPic;
using System.Windows.Navigation;
namespace MyApp
{
class ApiCall
{
public static string api_url = "http://myappsapiurl/api";
public static string content_type = "application/vnd.api+json";
public string requestData;
public string requestMethod;
public string resource_url; // the rest of the api url
public string requestResponse;
public async Task<string> initialize_request()
{
Debug.WriteLine("the resource used is "+ resource_url);
System.Uri myUri = new System.Uri(api_url+resource_url);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(myUri);
request.ContentType = content_type;
request.Method = requestMethod;
request.Accept = content_type;
request.BeginGetRequestStream(new AsyncCallback(await GetRequestStreamCallback), request);
Debug.WriteLine("have we returned yet?");
return requestResponse;
}
private async Task GetRequestStreamCallback(IAsyncResult callbackResult)
{
Debug.WriteLine("we are in the second method");
HttpWebRequest webrequest = (HttpWebRequest)callbackResult.AsyncState;
Stream postStream = webrequest.EndGetRequestStream(callbackResult);
byte[] byteArray = Encoding.UTF8.GetBytes(requestData);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
webrequest.BeginGetResponse(new AsyncCallback( await GetResponsetStreamCallback), webrequest);
}
private void GetResponsetStreamCallback(IAsyncResult callbackResult)
{
Debug.WriteLine("we are in the third method");
try
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
string responseString = "";
Stream streamResponse = response.GetResponseStream();
StreamReader reader = new StreamReader(streamResponse);
responseString = reader.ReadToEnd();
streamResponse.Close();
reader.Close();
response.Close();
requestResponse = responseString;
}
catch (Exception e)
{
//show user-friendly error message as well as detailed one.
//for better UI, consider using WPToolKit's CustomMessageBox to show these
Debug.WriteLine("something wrong happened. \nDetails: " + e.HResult.ToString());
}
}
}
}
Anyhelp fixing this is highly appreciated, i want intialize_request() to execute, wait for both GetRequestStreamCallback and GetResponseStreamCallback to finish, before returning the requestResponse
[Update] Based on the comments section, i have been advised to use AutoResetEvent
namespace MyApp
{
class ApiCall
{
public static string api_url = "http://myappapirul/api";
public static string content_type = "application/vnd.api+json";
public string requestData;
public string requestMethod;
public string resource_url; // the rest of the api url
public string requestResponse;
public static AutoResetEvent objAuto = new AutoResetEvent(false);
public string initialize_request()
{
Debug.WriteLine("the resource used is "+ resource_url);
System.Uri myUri = new System.Uri(api_url+resource_url);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(myUri);
request.ContentType = content_type;
request.Method = requestMethod;
request.Accept = content_type;
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
objAuto.WaitOne();
Debug.WriteLine("have we returned yet?");
return requestResponse;
}
private void GetRequestStreamCallback(IAsyncResult callbackResult)
{
Debug.WriteLine("we are in the second method");
HttpWebRequest webrequest = (HttpWebRequest)callbackResult.AsyncState;
Stream postStream = webrequest.EndGetRequestStream(callbackResult);
byte[] byteArray = Encoding.UTF8.GetBytes(requestData);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
webrequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), webrequest);
}
private void GetResponsetStreamCallback(IAsyncResult callbackResult)
{
Debug.WriteLine("we are in the third method");
try
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
string responseString = "";
Stream streamResponse = response.GetResponseStream();
StreamReader reader = new StreamReader(streamResponse);
responseString = reader.ReadToEnd();
streamResponse.Close();
reader.Close();
response.Close();
requestResponse = responseString;
}
catch (Exception e)
{
//show user-friendly error message as well as detailed one.
//for better UI, consider using WPToolKit's CustomMessageBox to show these
Debug.WriteLine("something wrong happened. \nDetails: " + e.HResult.ToString());
}
Debug.WriteLine("we are about to return to initialize_request");
objAuto.Set();
}
}
}
Problem now is, GetResponsetStreamCallback never starts, and it looks like i never return, because Debug.WriteLine("have we returned yet?");
never gets executed!
Like Stephen Cleary mentioned and since you are building for Windows Phone 8 please consider using HttpClient
instead of HttpWebRequest
class. The reasons behind this is not just that is "a lot easier".
As mentioned on VS forums:
HttpClient
is more like a head-less browser. It a powerfull and ideal tool if you are going to be creating many http request. For example you can set default headers and stuff. Here are the top 5 ways it differs from anHttpWebRequest
:
- An
HttpClient
instance is the place to configure extensions, set default headers, cancel outstanding requests and more.- You can issue as many requests as you like through a single
HttpClient
instance.HttpClients are not tied to particular HTTP server or host; you can submit any HTTP request using the same
HttpClient
instance.You can derive from
HttpClient
to create specialized clients for particular sites or patternsHttpClient
uses the new Task-oriented pattern for handling asynchronous requests making it dramatically easier to manage and coordinate multiple outstanding requests.
For more information, please read the whole post and refer to this link .
There are several examples and complete projects showing how to use HttpClient
in different ways and not just to load string but to create c# objects from JSON objects as well.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.