I am trying to call api and check its response, but when ever some wrong value is passed it stops the program. I want to add exception during request and response but not sure how to write in function.
This is how i call my REST call
public dynamic APICalls(JObject ljson, string endpoints, string method)
{
var httpReq = (HttpWebRequest)HttprequestObject(endpoints, method);
using (var streamWriter = new StreamWriter(httpReq.GetRequestStream()))
{
streamWriter.Write(ljson);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpReq.GetResponse();
var result = "";
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
return result;
//return "Success";
//not sure what to return
//here i have to add sql server code to enter into database
}
THis is code for request
public dynamic HttprequestObject(string endpoints, string method)
{
string url = Settings.API_TEST_VALUE + endpoints;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = method;
return httpWebRequest;
}
And right before request and right after response i want to catch exception.
At this point i have to catch exception
var httpResponse = (HttpWebResponse)httpReq.GetResponse();
If some one gives me hint how to catch that before it stops program.
There are 400, 401,402 errors, if something is wrong API sends json
For instance, while creating user :-- Email id already exists
But that points stops json and stops program..
Using try catch it will stop program, I want it to run and want to receive resposne.
Actually, API will send error .
For instance, status will be ;---401 UNAUTHORIZED
and resposnse will be
{ "reason": "Email already registered.", "success": false }
I am changed my code and
HttpWebResponse httpResponse;
try
{
//HttpWebResponse myHttpWebResponse = (HttpWebResponse)httpReq.GetResponse();
httpResponse = (HttpWebResponse)httpReq.GetResponse();
//myHttpWebResponse.Close();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
Console.WriteLine("This program is expected to throw WebException on successful run." +
"\n\nException Message :" + e.Message);
if (e.Status == WebExceptionStatus.ProtocolError)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return result;
//return "Success";
//not sure what to return
//here i have to add sql server code to enter into database
}
This is the new code, but I m not getting Json as return value, So i can show specific error.
For below Json what should I write?
{ "reason": "Email already registered.", "success": false }
please I m new to c# and if something is not clear please modify or ask question?
thank you
What you're looking for is called a try-catch statement:
try
{
var httpResponse = (HttpWebResponse)httpReq.GetResponse();
}
catch (WebException e)
{
// Here is where you handle the exception.
}
Using WebException as the type in the catch statement means only exceptions of that particular type will be caught.
In case an exception occurs, the e variable will contain exception details, such as a message passed from the method which three the exception and any inner exceptions encapsulated inside.
You can handle your web exceptions to get HttpStatusCode and Response Message this way:
public void SendAndGetResponseString()
{
try
{
// Here you call your API
}
catch (WebException e)
{
var result = GetResponceFromWebException(e);
if (result != null){
//
// Here you could use the HttpStatusCode and HttpResponseMessage
//
}
throw;
}
catch (Exception e)
{
// log exception or do nothing or throw it
}
}
private HttpRequestResponce GetResponceFromWebException(WebException e)
{
HttpRequestResponce result = null;
if (e.Status == WebExceptionStatus.ProtocolError)
{
try
{
using (var stream = e.Response.GetResponseStream())
{
if (stream != null)
{
using (var reader = new StreamReader(stream))
{
var responseString = reader.ReadToEnd();
var responce = ((HttpWebResponse) e.Response);
result = new HttpRequestResponce(responseString, responce.StatusCode);
}
}
}
}
catch (Exception ex)
{
// log exception or do nothing or throw it
}
}
return result;
}
public class HttpRequestResponce {
public HttpStatusCode HttpStatusCode { get;set; }
public string HttpResponseMessage {get;set;}
public HttpRequestResponce() { }
public HttpRequestResponce(string message, HttpStatusCode code)
{
HttpStatusCode=code;
HttpResponseMessage=message;
}
}
You encapsulate whatever method call or code block you want to prevent from throwing unhandled exceptions.
try
{
// code here
}
catch (Exception)
{
// here you may do whatever you want to do when an exception is caught
}
Ok,Finally I am able to Solve this.. Thanks everyone for you help.
This worked for me. I think I was not reading whole response.. So some how I think I realized and now its working ..
HttpWebResponse httpResponse;
try
{
httpResponse = (HttpWebResponse)httpReq.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
Console.WriteLine("This program is expected to throw WebException on successful run." +
"\n\nException Message :" + e.Message);
if (e.Status == WebExceptionStatus.ProtocolError)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
using (Stream data = e.Response.GetResponseStream())
using (var reader = new StreamReader(data))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Related
I have the following code:
public static string Get(string requestUri)
{
try
{
return GetStringAsync(requestUri).Result;
}
catch (AggregateException aggregateException)
{
Console.WriteLine(aggregateException);
throw;
}
}
When the try block throws an exception, the program goes as it should in the catch block and displays the information about the error.
The problem is that once arrived at the rethrow, the debugger stops and raises me again the same exception but at the same level, despite it is supposed to go up one level in the stack...
I did not find a solution on the Internet, all examples correspond to my code.
EDIT
Your solution is working for the code above, but I have another which doesn't work too :
public static string Post(string requestUriString, string s)
{
var request = (HttpWebRequest)WebRequest.Create(requestUriString);
var data = Encoding.ASCII.GetBytes(s);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
try
{
var response = (HttpWebResponse)request.GetResponse();
return new StreamReader(response.GetResponseStream()).ReadToEnd();
}
catch (WebException webException)
{
Console.WriteLine(webException);
throw;
}
}
The issue is the way AggregateException is handled; change your method to an async method (which eliminates the AggregateException wrapper), and throw will work as expected:
public static async Task<string> Get(string requestUri)
{
try
{
return await GetStringAsync(requestUri);
}
catch (Exception exception) // Or, specify the expected exception type
{
Console.WriteLine(exception);
throw; // can be caught in the calling code
}
}
This is basically my first API handling with C#, so I read and tried to create so I can handle the JSON, but I ain't getting any response, tried to display it in a label text, but I am not getting any error nor any response.
It is supposed to show the JSON in a label with answer with basic auth, so then, I can handle it, because I have been able to see the JSON if I log via POSTMAN, but if I run the code, all I see is nothing, even tho it is wrapped in a string.
public partial class callUni : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string strResponse = string.Empty;
strResponse = makeRequest();
answer.Text = strResponse;
}
public string makeRequest()
{
string strRequest = string.Empty;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(#"https://unicard-api.asf.edu.mx:8443/api/Acessos/Entradas");
request.Credentials = GetCredential();
request.PreAuthenticate = true;
request.Method = httpMethod.ToString();
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode != HttpStatusCode.OK)
{
throw new ApplicationException("error code = " + response.StatusCode);
}
//Vamos a procesar el JSON que viene de UNICARD
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
using (StreamReader reader = new StreamReader(responseStream))
{
strRequest = reader.ReadToEnd();
}
}
}
}
}
catch (Exception e) { };
return strRequest;
}
private CredentialCache GetCredential()
{
string url = #"https://unicard-api.asf.edu.mx:8443/api/Acessos/Entradas";
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new System.Uri(url), "Basic", new NetworkCredential(ConfigurationManager.AppSettings["xxxxx"], ConfigurationManager.AppSettings["xxxx"]));
return credentialCache;
}
}
}
You say "I am not getting any error nor any response.", but I think you are getting an error, but your line here is hiding it from you:
catch (Exception e) { };
Try either logging or displaying e.ToString() inside the catch block then investigating from there.
As a sidenote, Microsoft explicitly says not to throw ApplicationException. Either find a more relevant Exception class to use or throw Exception. https://msdn.microsoft.com/en-us/library/system.applicationexception%28v=vs.110%29.aspx#Remarks
I am using the C# HttpWebRequest.GetResponse with a URL that is not encoded. But when I inspect the request using fiddler I see that the URL is encoded. I wanted to confirm that HttpWebRequest Class is encoding the URL internally but could not find it in the documentation. Can someone point me to the documentation where i can find this or some other way to validate it?
KR
Here it is:
WebRequest.Create (you are using that method to create your HttpWebRequest object, right?) says "The Create method uses the requestUriString parameter to create a Uri instance that it passes to the new WebRequest"
https://msdn.microsoft.com/en-us/library/bw00b1dc(v=vs.110).aspx
The constructor for Uri (which is being called by the Create method) says it "parses the URI, puts it in canonical format, and makes any required escape encodings"
https://msdn.microsoft.com/en-us/library/z6c2z492(v=vs.110).aspx
//endpoint is url and method can be post or get... the below will help you to catch any errors from server..
make it a function so its wll be easy for you to use where ever you want ...
HttpWebRequest httpRequest = (HttpWebRequest)HttprequestObject(endpoints, method);
using (var streamWriter = new StreamWriter(httpRequest.GetRequestStream()))
{
streamWriter.Write(jsonObject);
streamWriter.Flush();
streamWriter.Close();
}
var result = "";
HttpWebResponse httpResponse;
try
{
httpResponse = (HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
Console.WriteLine("This program is expected to throw WebException on successful run." +
"\n\nException Message :" + e.Message);
if (e.Status == WebExceptionStatus.ProtocolError)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
using (Stream data = e.Response.GetResponseStream())
using (var reader = new StreamReader(data))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
or u want class and u want to use for creating api lib then just copy paste this class ..this is for c# but almost similer syntax for java ...
with this u can access any api or url or also used to pass json file to server ..
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ExternalAPIs_SynapsePay.Helpers
{
class RESTHelpers
{
public dynamic APICalls(JObject jsonObject, string endpoints, string method)
{
HttpWebRequest httpRequest = (HttpWebRequest)HttprequestObject(endpoints, method);
using (var streamWriter = new StreamWriter(httpRequest.GetRequestStream()))
{
streamWriter.Write(jsonObject);
streamWriter.Flush();
streamWriter.Close();
}
var result = "";
HttpWebResponse httpResponse;
try
{
httpResponse = (HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
Console.WriteLine("This program is expected to throw WebException on successful run." +
"\n\nException Message :" + e.Message);
if (e.Status == WebExceptionStatus.ProtocolError)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
using (Stream data = e.Response.GetResponseStream())
using (var reader = new StreamReader(data))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return result;
//return "Success";
//not sure what to return
//here i have to add sql server code to enter into database
}
public HttpWebRequest HttprequestObject(string endpoints, string method)
{
string url = Setting.API_TEST_VALUE + endpoints;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = method;
return httpWebRequest;
}
/// <summary>
/// This method is useful when you have to pass JSON as string not as object... This is basically a constructor..
/// Even if u pass json object it will accept, so no need to worry about that.
/// </summary>
/// <param name="ljson"></param>
/// <param name="endpoints"></param>
/// <param name="method"></param>
/// <returns></returns>
public dynamic APICalls(string jsonString, string endpoints, string method)
{
HttpWebRequest httpRequest = (HttpWebRequest)HttprequestObject(endpoints, method);
using (var streamWriter = new StreamWriter(httpRequest.GetRequestStream()))
{
streamWriter.Write(jsonString);
streamWriter.Flush();
streamWriter.Close();
}
var result = "";
HttpWebResponse httpResponse;
try
{
httpResponse = (HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
Console.WriteLine("This program is expected to throw WebException on successful run." +
"\n\nException Message :" + e.Message);
if (e.Status == WebExceptionStatus.ProtocolError)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
using (Stream data = e.Response.GetResponseStream())
using (var reader = new StreamReader(data))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
result = text;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return result;
//return "Success";
//not sure what to return
//here i have to add sql server code to enter into database
}
public void HttlpResponseObject(HttpWebRequest httpResponse)
{
var response = (HttpWebResponse)httpResponse.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
//entry into databse can be done from here
//or it should return some value
}
}
}
This question already has answers here:
Getting Http Status code number (200, 301, 404, etc.) from HttpWebRequest and HttpWebResponse
(6 answers)
Closed 9 years ago.
I am making an external API call in my system. If the user is not logged in code will generate a 404 error. I want to identify that error in my code. Is it possible?
Error look like this
And my Code is like this
public string ExecuteGetRequest()
{
try
{
_url = Qparams != null ? Utility.WEBAPI_ENDPOINT + Type + "?" + Qparams : Utility.WEBAPI_ENDPOINT + Type; ;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(_url);
if (!string.IsNullOrEmpty(SessionValues.UserID)&& !string.IsNullOrEmpty(SessionValues.AccessToken))
{
var handler = new HttpClientHandler();
handler.Credentials = new NetworkCredential(SessionValues.UserID, SessionValues.AccessToken);
string authInfo = SessionValues.UserID + ":" + SessionValues.AccessToken;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
string username = SessionValues.UserID;
String password = SessionValues.AccessToken;
String encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(username + ":" + password));
httpWebRequest.Headers.Add("Authorization", "Basic " + encoded);
}
httpWebRequest.Method = "GET";
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream(), Encoding.UTF8))
{
_result = streamReader.ReadToEnd();
}
}
catch (Exception ex)
{
Log.Add(LogTypes.Error,100, ex.ToString());
}
return _result;
}
Cast the exception to its actual type in order to get access to the WebResponse object. Then, cast that response object to HttpWebResponse in order to get the error code (and optionally, response content).
try
{
// ...
}
catch ( WebException ex )
{
var response = (HttpWebResponse) ex.Response;
var errorCode = response.StatusCode;
Log.Add(LogTypes.Error, errorCode, ex.Message);
}
you can select each line while debugging and right click on that and click add watch option there, by this you can identify which line is producing error.
If you look at the screenshot you posted you can see that the actual exception class is a System.Net.WebException. WebException has a lot of useful properties, including the WebResponse. You can cast that response to a HttpWebResponse and then query its status code. What you can do is add a specialized exception handler for WebExceptions.
try
{
// do your stuff
}
catch (WebException webEx)
{
var response = webEx.Response as HttpWebResponse;
if (response != null)
{
Log.Add(LogTypes.Error, 100, "HTTP StatusCode = " + (int)response.StatusCode);
}
}
catch (Exception ex)
{
Log.Add(LogTypes.Error, 100, ex.ToString());
}
First of all you should usually only catch specific types of exception instead of a catch all like you have done here so I would have your catch block as:
catch (WebException ex)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
}
}
Obviously instead of writing to console you can do whatever you want with StatusCode and Description.
You can explore all the inner exceptions as
catch(Exception ex)
{
string errorMessage = string.Empty;
while (ex.InnerException != null)
{
errorMessage += ex.Message + Environment.NewLine;
ex = ex.InnerException;
}
errorMessage += ex.Message + Environment.NewLine;
MessageBox.Show(errorMessage);
}
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);
}
}
}