How can i retrieve the http response status code from an url? - c#

I am automating a test for a page that contains a URL that needs to be then tested.
I created a method that I believed was giving me the http status code:
public string ContentUrlHttpRequest()
{
HttpWebRequest protocolWebRequest = (HttpWebRequest)WebRequest.Create(ContentUrl());
protocolWebRequest.Method = "GET";
HttpWebResponse response = (HttpWebResponse)protocolWebRequest.GetResponse();
return response.Headers.ToString();
}
ContentUrl() is another method i created to find the element on the page with the url to be tested and gets it's value.
I have also tried return response.StatusCode.ToString(); but the response i received was "OK".
I know that the response from that url needs to be = 200. I have this assertion that compares the response from the ContentUrlHttpRequest() to the expected results (200):
Assert.AreEqual("200", ContentUrlHttpRequest(), "The Url is not live. Http response = " + ContentUrlHttpRequest());
The response i am getting from ContentUrlHttpRequest() is not the status code but:"Date: Mon, 03 May 2021 09:07:13 GMT".
I understand why it is happening, it is getting the header of the page that is searching. But how could I get the status code? Is it possible with Selenium? Is there something wrong with my method and instead of Headers I need to use something different?
Unfortunately i am not able to provide with the urls that i am testing, or the platform with the url as they are confidential. Hopefully my issue is clear and you guys can give me some guidance.

You are not returning the response status code. You are returning the headers.
You should replace the return statement with this:
return ((int)response.StatusCode).ToString();

I guess you should use response.Status.ToString(); instead of response.Headers.ToString();
But the status contains not only the number like 200 or 401 but also text.
So if you are going to use response.Status.ToString(); you should Assert.True(ContentUrlHttpRequest().contains("200"))
Or you can use response.StatusCode.ToString(); this will give you the status number itself String without additional texts.

Related

Why am I getting response status code 204 No Content in my WebApi?

First of all, my English is not so good, I hope you understand what I am trying to say.
I'm new with WebApi's. I created one and all seems good. In my function I return a string, but when I test the web api with Postman it returns a status code 204 no content.
I looked for this status and apparently my request was succeded, but when I look at my database nothing happend. (my function saves some data in my database and returns a string when it is succeded or not).
So, my question is, Why am I receiving this status code when my function must to return a string? Or why when I test the Web Api with Postman it returns a 204 No Content code (that means my request was succeded) when is not true (because nothing was saved in my database)?
Here is my function in my web api:
[HttpPost]
public string IncomingPO(string request)
{
//do some stuff
return "response as a string";
}
My parameter "string request" is a string that cointains a xml. I read the string as a xml and do some stuff with it. (save some nodes from the xml in a database, for example).
If all the function is succeded or not I expect the output of my string, but I'm no receiving anything. Only the status code 204 No Content. (when content should really be returned).
Any suggestion is welcome.
It can solve my problem.
The only thing I had to do was specify the route with which my Api website will be invoked.
In addition I also had to modify the data type of my parameter and my function.
Something like this:
[HttpPost]
[Route("api/Controller/IncomingPO")]
public HttpResponseMessage IncomingPO(HttpRequestMessage request)
{
//do some stuff
return new HttpResponseMessage()
{
Content = new StringContent("My response string", System.Text.Encoding.UTF8, "application/xml"),
StatusCode = HttpStatusCode.OK
};
}

Is there a way to retrieve the String the way it is actually uploaded to the server (as a whole)?

I am currently working on a OAuth2 implementation. However I am stuck on an Error 401. It seems like there is something wrong with my post request that is supposed to retrieve the access token from the Company the User logged in to. This is my code:
internal void RequestAccessToken(string code)
{
string requestBody = "grant_type="+ WebUtility.UrlEncode(GRANTTYPE)+ "&code=" + WebUtility.UrlEncode(code)+"&redirect_uri="+ WebUtility.UrlEncode(REDIRECT_URI);
WebClient client = new WebClient();
client.Headers.Add("Authorization",HeaderBase64Encode(CLIENT_ID, SECRETKEY));
var response = client.UploadString("https://thewebsiteiamcallingto.com/some/api", requestBody);
var responseString = client.OpenRead("https://thewebsiteiamcallingto.com/some/api");
}
My Questions are:
Is there anything wrong with the way I try to make the POST request ?
Is there a way to retrieve the whole string that is posted to the URI using UploadString?
P.S. I have seen this post regarding the POST creation. However I find the async part to be too complicated for my case.
Since we dont know the api documentation, I would suggest you to make a postman request and view the actual request sent and response received, and secondly make a request using your method and capture using a utility like wireshark and compare the difference.

How can I know from the URL if it is the correct image URL or not in C#?

I have an array of images URLs. I want to know which of these URLs are correct and which not, without using try-catch, and I want to do that as fast as possible.
I would think the only way for you to know which urls are correct is to just make an HTTP request to the URL. If you have a lot of pictures, this will always take time. You can minimize that time by just making a HEAD HTTP request (as opposed to a GET and downloading the whole response), and checking the status code of the response. If the status code is 200, you might assume that you get the picture you're looking for, if it is 404, you know the url is incorrect.
Code might be something like:
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://example.com/");
req.Method = "HEAD";
HttpWebResponse resp = (HttpWebResponse)(req.GetResponse());
HttpStatusCode statuscode = resp.StatusCode;
A note on getting a 200 response: If you get a 200 repsonse, you cannot be sure that you are actually getting image you want. You might be getting something else, e.g. a redirect from the image url.

HttpWebRequest vs Webclient (Special scenario)

I know this question has been answered before in this thread, but I couldn't seem to find the details.
In my scenario, I am building a console application which will keep an eye on html page source for any changes. If any update/change occurs, I will perform further operations. Moreover, I'll also perform a request after every 1 second, or as soon as the previous request finishes.
I can't seem to figure out should I use HttpWebRequest or WebClient for downloading the html page source and perform comparison? What do you think would be an ideal solution in my case? Speed and reliability both :)
I'd go with HttpWebRequst because it's not as abstracted and lets you fiddle with HTTP params quite a bit. It gives you the option to not download the entire page if the server returns "file not changed", for example.
If you add some parameters to your request like IfModifiedSince (it might be HEAD or GET request) the server may return the response code 304 - NOT MODIFIED. Refer to description of caching in HTTP for further explanation.
The point is to make sure that you only download the full page when it's actually modified since the last time you fetched it. Most of the time it won't be changed (I suppose, can't know for sure without knowing your domain), so you only need to get a lightweight response from server which simply states "nothing changed here".
Update: code sample demonstrating the use of IfModifiedSince property:
bool IsResourceModified(string url, DateTime dateTime) {
try {
var request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
request.IfModifiedSince = dateTime;
request.Method = "HEAD";
var response = (HttpWebResponse)request.GetResponse();
return true;
}
catch(WebException ex) {
if(ex.Status != WebExceptionStatus.ProtocolError)
throw;
var response = (HttpWebResponse)ex.Response;
if(response.StatusCode != HttpStatusCode.NotModified)
throw;
return false;
}
}
This method should return true if the page was modifed since the dateTime date and false if it wasn't. GetResponse method will throw a WebException if you make a HEAD-request and the server returns 304 - NOT MODIFIED (which is kinda unfortunate). We have to make sure that it's not some other web connection problem, that's why I check the status of web exception and the HTTP status in response. If anything else caused an exception we just throw it further.
Console.WriteLine(IsResourceModified("http://example.com", new DateTime(2009)));
Console.WriteLine(IsResourceModified("http://example.com", DateTime.Now));
This sample code produces the output:
True
False
Note: make sure to read Jim Mischel's addition to this answer as he gives few good advices on this technique.
I was going to leave this as a comment to #Dyppl's response, but it became too long.
Dyppl's response is generally good advice, and the way that I would approach this problem. However, there are a few things you should keep in mind.
First, there's no reason to do a HEAD request, followed by a GET if the page has been modified. You can do a GET with the IfModifiedSince header set, and the server will either return the entire page or a 304. Doing the HEAD first, followed by the 'GET`, ends up making two requests to the server, which defeats much of the purpose of the conditional request.
Second, you should set the IfModifiedSince property to the LastModified value returned by the previous response (i.e. HttpWebResponse.LastModified) because the server's time might not be synchronized with your computer. Also, I've found that a large percentage of sites, particularly those with generated content (like WordPress blogs) lie. They always return the current date/time in the LastModified header. As a result, there is no benefit to doing the If-Modified-Since check on those sites.
If you know that the site lies and always returns the current date/time, you can keep track of the ContentLength header that's returned from the page when you download it. Then, when you want to check to see if the page has changed, do a HEAD request and check the returned ContentLength header with the saved value. If they match, then it's unlikely that the page has changed. If they don't match, then do a GET request to update your copy of the page and keep the new ContentLength.
This technique does have the disadvantage of requiring two requests if the page has changed. It's also not 100% reliable on all servers. Some will return a different ContentLength for the HEAD request, and some don't return a valid ContentLength at all. That said, I've found it to be effective for a large number of sites.

Determine Final Destination of a Shortened URL

I'm trying to find the best way (in code) to determine the final destination of a shortened URL. For instance http://tinyurl.com redirects to an eBay auction. I'm trying to get the URL for the eBay auction. I'm trying to do this from within .NET so I can compare multiple URLs to ensure that there is no duplicates.
TIA
While I spent a minute writing the code to ensure that it worked the answer was already delivered, but I post the code anyway:
private static string GetRealUrl(string url)
{
WebRequest request = WebRequest.Create(url);
request.Method = WebRequestMethods.Http.Head;
WebResponse response = request.GetResponse();
return response.ResponseUri.ToString();
}
This will work as long as the short url service does a regular redirect.
You should issue a HEAD request to the url using a HttpWebRequest instance. In the returned HttpWebResponse, check the ResponseUri.
Just make sure the AllowAutoRedirect is set to true on the HttpWebRequest instance (it is true by default).
One way would be to read the URL and get the result code from it. If it's a 301 (permanent redirect) then follow where it's taking you. Continue to do this until you reach a 200 (OK). When using tinyurl it could happen that you will go through several 301 until you reach a 200.
Assuming you don't want to actually follow the link, for TinyURL you can append /info to the end of the url:
http://tinyurl.com/unicycles/info
and it gives you a page showing where that tinyurl links to, which I assume would be easy to parse using xpath or similar.
Most other URL shortening services have similar features, but they all work differently.

Categories