c# catch empty Json / 404 error - c#

I have the following code for accessing a Api which returns a Json value. Now it's possible that i try to access the api but nothing is being returned, aka the given ID its trying to search doesnt exist. This ofcourse returns a 404 but i do not know how to handle this error so the code continious on going, now it breaks the program and crashes.
public RootObject GetApi(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);
var jsonReader = new JsonTextReader(reader);
var serializer = new JsonSerializer();
return serializer.Deserialize<RootObject>(jsonReader);
}
}
catch (WebException ex){
WebResponse errorResponse = ex.Response;
using (Stream responseStream = errorResponse.GetResponseStream()){
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
// log errorText
}
throw;
}
}
This is the button click event where the Url of the api is given.
private void button1_Click(object sender, EventArgs e)
{
result_rTBox.Text = "";
api_Handler api_Handler = new api_Handler();
string spidyApi_itemSearch = "http://www.gw2spidy.com/api/v0.9/json/item-search/";
string Gw2Api_allListings = "https://api.guildwars2.com/v2/commerce/listings/";
string userInput_itemName = userSearchInput_tBox.Text;
string spidyApi_searchIdByName = spidyApi_itemSearch + userInput_itemName;
if (!string.IsNullOrWhiteSpace(userSearchInput_tBox.Text)){
var spidyApi_searchIdByName_result = api_Handler.GetApi(spidyApi_searchIdByName);
var Gw2Api_isItemIdinListing_result = api_Handler.GetApi(Gw2Api_allListings + spidyApi_searchIdByName_result.results[0].data_id);
//result_rTBox.Text = Gw2Api_isItemIdinListing_result.results[0].data_id.ToString();
}
}
First i access the api with string "spidApi_itemSearch" and after that I have and ID that i need to check if exists in the api Gw2Api_allListings. If it doesnt exist, which will happen quite often, it returns nothing with a 404 error. How do i get around of making the code continue even if it returns nothing?
EDIT: code that i have now, still crashes on the break.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
try
{
var requesting = WebRequest.Create(url);
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
var jsonReader = new JsonTextReader(reader);
var serializer = new JsonSerializer();
return serializer.Deserialize<RootObject>(jsonReader);
}
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError &&
ex.Response != null)
{
var resp = (HttpWebResponse)ex.Response;
if (resp.StatusCode == HttpStatusCode.NotFound){
}
}
throw;
}
}

Use the HttpStatusCode Enumeration, specifically HttpStatusCode.NotFound
Instead of WebResponse, try using HttpWebResponse
HttpWebResponse errorResponse = we.Response as HttpWebResponse;
if (errorResponse.StatusCode == HttpStatusCode.NotFound) {
// handle the error here
}
Where we is a WebException

Related

How do I read a custom error message returned when HttpWebRequest.GetResponse throws a WebException?

I've a NET.Core API with simple test method:
public async Task<IActionResult> TestApi()
{
try
{
throw new UnauthorizedAccessException("My custom error");
return Ok();
}
catch (UnauthorizedAccessException ex)
{
return StatusCode(401,ex.Message);
}
catch (Exception ex)
{
throw;
}
}
I need to retrieve the message from a client like this:
var request = WebRequest.Create($"{baseUrl}{url}") as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json";
request.Expect = "application/json";
request.ContentLength = 0;
if (parameters != null)
{
request.ContentLength = serializedObject.Length;
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(serializedObject);
}
}
var response = request.GetResponse() as HttpWebResponse;
var responseEncoding = Encoding.GetEncoding(response.CharacterSet);
using (var sr = new StreamReader(response.GetResponseStream(), responseEncoding))
{
var result = sr.ReadToEnd();
return JsonConvert.DeserializeObject<T>(result);
}
Now request.GetResponse() as HttpWebResponse returns me:
The remote server returned an error: (401) Unauthorized.
instead of My custom error. Can someone point me in the right direction?
Here's a pared-down example which reads your custom message. Your message is returned in the response stream.
try
{
var response = request.GetResponse() as HttpWebResponse;
}
catch (WebException ex) // this exception is thrown because of the 401.
{
var responseStream = ex.Response.GetResponseStream();
using (var reader = new StreamReader(responseStream))
{
var message = reader.ReadToEnd();
}
}
Return an ActionResult
Task<ActionResult>
You can then wrap up the unauthorized error in an UnauthorizedObjectResult
return Unauthorized(new UnauthorizedObjectResult(errorModel));

Why does my API POST Request keep failing?

I am doing an API Post request and cant seem to get it to work. I always get a sendFailure webexception and the response for the exception is always null so catching the exception is useless. It keeps happening when I try to get the httpWebResponse. I noticed too the request.contentlength gave errors at postream getrequeststream so i commented it out. Test.json is the file I use for the request body. I also tested this on different API testers by including the URL, body, and content-type in the header and they worked. I just cant seem to code it for myself. The credentials work I just dont know if im doing the request correctly?
JSON File:
{
"email": "abc#123.com",
"password": "12345",
"facilityNumber": "987654"
}
string filepath = "test.json";
string result = string.Empty;
using (StreamReader r = new StreamReader(filepath))
{
var json = r.ReadToEnd();
var jobj = JObject.Parse(json);
foreach (var item in jobj.Properties())
{
item.Value = item.Value.ToString().Replace("v1", "v2");
}
result = jobj.ToString();
Console.WriteLine(result);
}
try
{
string setupParameters;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://www.test.com/abcde");
request.AllowAutoRedirect = true;
setupParameters = result;
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
ASCIIEncoding encoding = new ASCIIEncoding();
var postData = setupParameters;
request.Method = "POST";
request.ContentType = "application/json";
byte[] data = encoding.GetBytes(postData);
//request.ContentLength = data.Length;
using (StreamWriter postStream = new StreamWriter(request.GetRequestStream()))//error if uncomment contentlength
{
postStream.Write(postData);
postStream.Flush();
postStream.Close();
}
HttpWebResponse wr = (HttpWebResponse)request.GetResponse();//error occurs
Stream receiveStream = wr.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
}
catch (WebException ex)
{
if (ex.Response != null)
{
using (var errorResponse = (HttpWebResponse)ex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
result = error;
}
}
}
I suggest modifiying your request to follow this format. Especially pay attention to the request.Method and request.ContentType which have caught me out multiple times.
Also, handling the response is easier this way.
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(YOURURL);
request.ContentType = "application/json; charset=utf8";
request.Headers.Add(ADD HEADER HERE IF YOU NEED ONE);
request.Method = WebRequestMethods.Http.Post; // IMPORTANT
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(JsonConvert.SerializeObject(JSONBODYSTRING));
// I USUALLY YOU JSONCONVERT HERE TO SIMPLY SERIALIZE A STRING CONTAINING THE JSON INFO.
//BUT I GUESS YOUR METHOD WOULD ALSO WORK
streamWriter.Flush();
streamWriter.Close();
}
WebResponse response = request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
string result = streamReader.ReadToEnd();
// DO WHATEVER YOU'D LIKE HERE
}
} catch (Exception ex)
{
// HANDLE YOUR EXCEPTIONS
}

API WebService Not responding anything

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

How to get json data in REST endpoint C#

i set the Transaction response callback url of an API to : https://requestb.in/st4fz3st and it gives me a response ok, on debugging the response process by checking the link https://requestb.in/st4fz3st?inspect the results shown in the image below.
i want to get the json data so i wrote this c# code
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;
using (Stream responseStream = errorResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
return errorText;
}
throw;
}
}
protected void Page_Load(object sender, EventArgs e)
{
x = GET(" https://requestb.in/st4fz3st");
Response.Write(x);
}
But what i get is the ok not the RAW BODY which is marked in red.
You can use the api. For example in your case: https://requestb.in/api/v1/bins/st4fz3st/requests
You can parse the result with Newtonsoft.Json. The 'raw body' is body property

Web service request time out issue

I want to interact with a web service, and for this purpose I am using this code.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(#"http://192.168.2.51/loodappSrv/LoodAppsrv.svc/company/insertcompany?Validation_Token=dc6f3d5e-22c7-405f-abb6-4491de140e7e");
req.Method = "POST";
req.ContentType = #"text/json";
JsonComapnyFormat jcf = new JsonComapnyFormat();
string data = jcf.data();//data in json Format {"companyName":"Alpha","departmentId":3}
using (Stream requestStream = req.GetRequestStream())
{
StreamWriter streamWriter = null;
try
{
//streamWriter = new StreamWriter(requestStream, System.Text.Encoding.Default);
streamWriter = new StreamWriter(requestStream, System.Text.Encoding.Default);
streamWriter.Write(data);
}
catch (Exception ex)
{
throw ex;
}
finally
{
try
{
streamWriter.Close();
requestStream.Close();
streamWriter.Dispose();
streamWriter = null;
requestStream.Dispose();
}
catch
{
}
}
}
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
var result = reader.ReadToEnd();
ViewBag.ABC = result;
return View();
If I Use Fiddler to send POST data on the given URL, it is perfect (sudden response comes out). But when I send same date on the same URL then the message return in an exception "The operation has timed out" at HttpWebResponse response = (HttpWebResponse)req.GetResponse();. Please suggest solutions.
Have you tried what SLaks mentioned ?
The MIME media type for JSON text is application/json.
As can be seen here

Categories

Resources