I am POSTING XML data using WebClient.
public string uploadXMLData(string destinationUrl, string requestXml)
{
try
{
System.Uri uri = new System.Uri(destinationUrl);
using (WebClient client = new WebClient())
{
client.Headers.Add("content-type", "text/xml");
var response = client.UploadString(destinationUrl, "POST", requestXml);
}
}
catch (WebException webex)
{
WebResponse errResp = webex.Response;
using (Stream respStream = errResp.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream);
string text = reader.ReadToEnd();
}
}
catch (Exception e)
{ }
return null;
}
When there is an error, I catch it as WebException, and I read the Stream in order to know what the XML response is.
What I need to do, is post the XML data to the URL in Async.
So I changed the function:
public string uploadXMLData(string destinationUrl, string requestXml)
{
try
{
System.Uri uri = new System.Uri(destinationUrl);
using (WebClient client = new WebClient())
{
client.UploadStringCompleted
+= new UploadStringCompletedEventHandler(UploadStringCallback2);
client.UploadStringAsync(uri, requestXml);
}
}
catch (Exception e)
{ }
return null;
}
void UploadStringCallback2(object sender, UploadStringCompletedEventArgs e)
{
Console.WriteLine(e.Error);
}
How can I catch the WebException now and read the XML response?
Can I throw e.Error?
Any help would be appreciated
I found the solution:
void UploadStringCallback2(object sender, UploadStringCompletedEventArgs e)
{
if (e.Error != null)
{
object objException = e.Error.GetBaseException();
Type _type = typeof(WebException);
if (_type != null)
{
WebException objErr = (WebException)e.Error.GetBaseException();
WebResponse rsp = objErr.Response;
using (Stream respStream = rsp.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream);
string text = reader.ReadToEnd();
}
throw objErr;
}
else
{
Exception objErr = (Exception)e.Error.GetBaseException();
throw objErr;
}
}
}
Related
I have a dynamic page with a .JSON file, and I'm using my C# program to access it every x number of seconds, to determine if something has been changed or not. Everything works flawlessly as long as I have Internet connection, if for whatever reason I lose it, then my program crashes as the ex.Response is a null. I was wondering if there's a better way of handling the following code:
void Function(){
while(true){
jList = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<jsonList>(GET(jsonUrl));
//SOME THINGS I DO with the data above here
Thread.Sleep(5000);
}}
string GET(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
try
{
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
catch (WebException ex)
{
WebResponse errorResponse = ex.Response;
if (ex.Response != null) {
using (Stream responseStream = errorResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
// log errorText
}
}
throw;
}
}
Perhaps I should ping it first, and see if I get a reply, and only then Perform the WebRequest function?
EDIT:
After adding this
public bool getResponse(string URL)
{
try
{
WebClient wc = new WebClient();
string HTMLSource = wc.DownloadString(URL);
return true;
}
catch (Exception)
{
return false;
}
}
And use it as
void Function(){
while(true){
if (!getResponse(jsonUrl))
{
return;
}
jList = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<jsonList>(GET(jsonUrl));
//SOME THINGS I DO with the data above here
Thread.Sleep(5000);
}}
My C# application waits a bit, and then exits normally. Why?
The program '[10476] Kiosk2.vshost.exe' has exited with code 0 (0x0).
Alright, well this seems to work fine for me.
public void Update() //CALLED IT void FUNCTION earlier
{
while (true)
{
while (getResponse(jsonUrl))
{
jList = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<jsonList>(GET(jsonUrl));
//I DO SOME STUFF HERE
//INTERESTING STUFF
Thread.Sleep(5000);
}
}
}
And seconds function:
public bool getResponse(string URL)
{
try
{
WebClient wc = new WebClient();
string HTMLSource = wc.DownloadString(URL);
return true;
}
catch (Exception)
{
return false;
}
}
I am trying to call a web service
which returns a JSON response. So far my code is working fine for GET Request but now services on server are POST and I have no idea how to do that! Below is the code for GET Request:
private void callSigninWebservice()
{
setProgressIndicator(true);
SystemTray.ProgressIndicator.Text = "Signing in please wait";
try
{
WebClient webClient = new WebClient();
Uri uri = new Uri(GlobalVariables.URL_USER +
GlobalVariables.URL_STUDENT_SIGNIN_MODE_LOGIN +
GlobalVariables.URL_EMAIL + tbUsername.Text +
GlobalVariables.URL_PASSWORD + tbPassword.Password);
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(uri);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "error came here 1");
}
}
For Response
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
try
{
JObject parentObj = JObject.Parse(e.Result);
String strResult = (String)parentObj[SigninData.JSON_result];
bool bolresult = strResult.Equals(SigninData.JSON_result_success, StringComparison.Ordinal);
if (bolresult)
{
JObject dataObj = (JObject)parentObj[SigninData.JSON_data];
setUserData(dataObj);
NavigationService.Navigate(new Uri("/BasePage.xaml", UriKind.RelativeOrAbsolute));
}
else
{
String error = (String)parentObj[SigninData.JSON_data];
MessageBox.Show("Error : " + error);
}
setProgressIndicator(false);
}
catch (Exception)
{
setProgressIndicator(false);
}
}
This is a simple way of making a post request and receiving a response in JSON for future parse:
internal static async Task<String> GetHttpPostResponse(HttpWebRequest request, string postData)
{
String received = null;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
byte[] requestBody = Encoding.UTF8.GetBytes(postData);
// ASYNC: using awaitable wrapper to get request stream
using (var postStream = await request.GetRequestStreamAsync())
{
// Write to the request stream.
// ASYNC: writing to the POST stream can be slow
await postStream.WriteAsync(requestBody, 0, requestBody.Length);
}
try
{
// ASYNC: using awaitable wrapper to get response
var response = (HttpWebResponse)await request.GetResponseAsync();
if (response != null)
{
var reader = new StreamReader(response.GetResponseStream());
// ASYNC: using StreamReader's async method to read to end, in case
// the stream i slarge.
received = await reader.ReadToEndAsync();
}
}
catch (WebException we)
{
var reader = new StreamReader(we.Response.GetResponseStream());
string responseString = reader.ReadToEnd();
Debug.WriteLine(responseString);
return responseString;
}
return received;
}
So I'm using the HttpWebRequest API in the System.Net assembly but because C# has no checked exceptions, I'm not sure where to put my try-catch blocks to properly handle inevitable exceptions caused by common things like a network error. You know, in Java we would call these plain old checked IOExceptions.
This is what I have so far. Are my try-catch blocks properly set up to handle network errors? Am I wrapping the right method calls? Looking at the documentation, I think they are right, but I need a second pair of eyes.
HttpWebRequest request = WebRequest.CreateHttp(url);
request.Method = "POST";
request.BeginGetRequestStream(getRequestResult =>
{
HttpWebRequest getRequestRequest = (HttpWebRequest) getRequestResult.AsyncState;
try
{
Stream requestStream = getRequestRequest.EndGetRequestStream(getRequestResult);
requestStream.Write(parametersData, 0, parametersData.Length);
requestStream.Dispose();
getRequestRequest.BeginGetResponse(getResponseResult =>
{
HttpWebRequest getResponseRequest = (HttpWebRequest)getResponseResult.AsyncState;
try
{
WebResponse response = getResponseRequest.EndGetResponse(getRequestResult);
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string jsonString = reader.ReadToEnd();
reader.Dispose();
JObject jsonObject = JObject.Parse(jsonString);
onResult(StatusCode.Ok, jsonObject);
}
catch (WebException)
{
onResult(StatusCode.NetworkError);
}
}, getRequestRequest);
}
catch (IOException)
{
onResult(StatusCode.NetworkError);
}
}, request);
First off, unless there's some reason that you need to use HttpWebRequest, then you're better off using WebClient.UploadString instead, or any of WebClient's other UploadXXX overloads for uploading name/value pairs, files, binary data, etc. This will be much easier for you, and easier to troubleshoot and debug. Also, another problem is that you're treating exceptions during JSON parsing or during your onResult handler error as network errors.
Below are three examples of using WebClient that you might want to try: a synchronous version, an "old-style" async version, and a "new-style" async version that uses async/await. All three versions also try to fix the exception handling issue that I noted above. If you don't need async support, then the first version will be easiest.
static void PostSync (string url, string parametersData)
{
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; // or "application/json" or ...
try
{
string htmlResult = wc.UploadString(url, parametersData); // or UploadValues, UploadFile, ...
JObject jsonObject = null;
try
{
jsonObject = JObject.Parse(htmlResult);
}
catch (JsonException ex)
{
onResult(StatusCode.JsonError);
}
onResult(StatusCode.Ok, jsonObject);
}
catch (System.Net.WebException ex)
{
onResult(StatusCode.NetworkError);
}
}
}
static void PostAsync(string url, string parametersData)
{
using (WebClient wc = new WebClient())
{
wc.UploadStringCompleted += (Object sender, UploadStringCompletedEventArgs e) =>
{
if (e.Error != null)
onResult(StatusCode.NetworkError);
JObject jsonObject = null;
try
{
jsonObject = JObject.Parse(e.Result);
}
catch (JsonException ex)
{
onResult(StatusCode.JsonError);
}
onResult(StatusCode.Ok, jsonObject);
};
try
{
wc.UploadStringAsync(new Uri(url, UriKind.Absolute), parametersData);
}
catch (System.Net.WebException ex)
{
onResult(StatusCode.NetworkError);
}
}
}
static async void PostTaskAsync(string url, string parametersData)
{
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; // or "application/json" or ...
try
{
string htmlResult = await wc.UploadStringTaskAsync(url, parametersData); // or UploadValues, UploadFile, ...
JObject jsonObject = null;
try
{
jsonObject = JObject.Parse(htmlResult);
}
catch (JsonException ex)
{
onResult(StatusCode.JsonError);
}
onResult(StatusCode.Ok, jsonObject);
}
catch (System.Net.WebException ex)
{
onResult(StatusCode.NetworkError);
}
}
}
I have the following code:
public class Request
{
static string username = "ha#gmail.com";
public string Send()
{
///some variables
try
{
///
}
catch (WebException e)
{
using (WebResponse response = e.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream Data = response.GetResponseStream())
{
string text = new StreamReader(Data).ReadToEnd();
}
}
}
return text;
}
}
Getting an error: 'text' does' t exist in the current context. How to return the 'Text' value from the method.
public string Send()
{
//define the variable outside of try catch
string text = null; //Define at method scope
///some variables
try
{
///
}
catch (WebException e)
{
using (WebResponse response = e.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream Data = response.GetResponseStream())
{
text = new StreamReader(Data).ReadToEnd();
}
}
}
return text;
}
public string Send()
{
try {
return "Your string value";
}
catch (WebException e) {
using (WebResponse response = e.Response) {
HttpWebResponse httpResponse = (HttpWebResponse)response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream Data = response.GetResponseStream())
{
return new StreamReader(Data).ReadToEnd();
}
}
}
}
You have to initialize variable before try clause to use it outside of try:
public string Send()
{
string text = null;
try
{
}
catch (WebException e)
{
using (WebResponse response = e.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream Data = response.GetResponseStream())
{
text = new StreamReader(Data).ReadToEnd();
}
}
}
return text;
}
You need to define text as a local variable in Send(), not inside a sublocal block like here inside using(...). Such it would be only valid there.
private void RespCallback(IAsyncResult asynchronousResult)
{
try
{
WebRequest myWebRequest1 = (WebRequest)asynchronousResult.AsyncState;
// End the Asynchronous response.
WebResponse webResponse = myWebRequest1.EndGetResponse(asynchronousResult);
}
catch (Exception)
{
// TODO:Log the error
}
}
Now having the webResponse object, what is the easiest way to read its contents?
I would simply use the async methods on WebClient - much easier to work with:
WebClient client = new WebClient();
client.DownloadStringCompleted += (sender,args) => {
if(!args.Cancelled && args.Error == null) {
string result = args.Result; // do something fun...
}
};
client.DownloadStringAsync(new Uri("http://foo.com/bar"));
But to answer the question; assuming it is text, something like (noting you may need to specify the encoding):
using (var reader = new StreamReader(response.GetResponseStream()))
{
string result = reader.ReadToEnd(); // do something fun...
}
Here is one way to do it if the response is coming in from XML.
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("https://www.yoururl.com");
WebResponse response = myReq.GetResponse();
Stream responseStream = response.GetResponseStream();
XmlTextReader reader = new XmlTextReader(responseStream);
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Text)
{
Console.WriteLine("{0}", reader.Value.Trim());
}
Console.ReadLine();
}
internal string Get(string uri)
{
using (WebResponse wr = WebRequest.Create(uri).GetResponse())
{
using (StreamReader sr = new StreamReader(wr.GetResponseStream()))
{
return sr.ReadToEnd();
}
}
}