StreamReader, Bad Request (400) - c#

We have a website that allow firmware downloads.
Somwhere along the way it uses a StreamReader. For some unknown reason, some customer (In Israel) get a 400 Bad Request error. Everyone else do not get this error.
Any1 out there experienced the same thing ? Anyone got a clue ?
protected void Page_Load(object sender, EventArgs e)
{
string strURL = Request.Url.Host;
System.Net.WebRequest reqPT = System.Net.WebRequest.Create("http://" + strURL + "/Products/ProductTree.asp");
System.IO.StreamReader srPT = new System.IO.StreamReader(reqPT.GetResponse().GetResponseStream());
dvPT.Controls.Add(new LiteralControl(srPT.ReadToEnd()));
}
It crashes, for them only, at the new StreamReader.
Thank you !
UPDATE : We noticed that the customer is actually loosing the "www" in the address (strURL), wich cause the error. Why would someone, (clicking on the same link as the rest of the planet is) would loose the www ?? I'm seeing 2 differents behavior for the exact same code :S

Well with the HTTP 400 error the requested URL is probably invalid, and since the literals in your System.Net.WebRequest look OK, my guess is your Israeli user is requesting the page using a different Request.Url.Host than everyone else. Can you debug and verify the value of strUrl?

Related

I need an api that can upload some data to the web

I have an application made with c# which gets something from the user.
I need that piece of information to be submitted to me somehow by that application downloading a string,
for example, I have seen URL shortener APIs that would take a request, then shorten something, and that target URL would appear in my account.
I was thinking something along the lines of:
private void example_click(object sender, EventArgs e)`
{
WebClient wc1 = new WebClient();
string datatosend = "example"
string received = wc1.DownloadString("https://examplesite.com/api?=" + datatosend + "&format=json");
}
Or something along those lines, I used the main format of the shrinkearn API https://shrinkearn.com/, however, I think that there might be a site with their own API that works in this way.
Reference: DownloadString
Thanks in advance
Martin

c# httpclient POST request: cant send special characters

I have a program that should login to site, it uses POST requests, and all goes fine, until one of the values contain special character('%' for example).
captcha = "ABCDE" //all goes fine and well, server accept captcha
captcha = "ABC&%" //server dont accept captcha and return fail
//here is the bad part:
string request = "password=" + HttpUtility.UrlEncode(encpass, Encoding.UTF8) +
"&username=" + login + "&captcha_text=" + HttpUtility.UrlEncode(captcha, Encoding.UTF8);
Also, i ofcourse googled it, and checked all i could find. I though i need to "warn" server abaut encoding, so i added
request.Headers.TryAddWithoutValidation("Content-Type", #"application/x-www-form-urlencoded; charset=UTF-8");
but it still did not helped me.
Content types and way request should look like i get from Firebug, so if i can find some answers there - please point.
modify0: Also, i compared what my program send to server with browser request(using Firebug) and my request is completley same. Only difference - my request dont get accepted in values it contain special-characters.
modify1: Also, server have no problems handling special-characters when i check it in browser. For example it(browser) sent "K&YF82" as "captcha_text=K%26YF82"(same value in addres propereties and request body) and all worked fine. UrlEncode do same replacement, but in my program it doesnt get accepted by server.
SOLUTION:
{ password:"df464dsj", username:"username", captchaText:"ABC&%", remember_login:"false" }
insteat of
password=f2341f14f&username=username&captha...
Are you dealing with REST application??
If yes then send your post data in request body instead of query string.
Also have a look at the stack post at : Special characters pose problems with REST webservice communication

WebClient failing on physical device and emulator

UPDATE:
Maybe it's just me not understanding how oAuth works? I tried running
the query manually on http://www.apikitchen.com and I get a 400 error
there too! Just to be sure, am I constructing the URL correctly here?
POST URL:
https://api.bufferapp.com/1/oauth2/token.json?client_id=[hidden]&client_secret=[hidden]&redirect_uri=http://apps.joel-murphy.com/buffer/code/success.php&code=[the
access code I get from buffer starting with
1/]&grant_type=authorization_code
Original post:
I'm building a Windows Phone application which requires the use of data from a website. The website uses oAuth to authenticate users.
I used the built in web browser control to make a GET request to authenticate users. The official documentation requires the URL structure to be like this:
GET https://bufferapp.com/oauth2/authorize?
client_id=...&
redirect_uri=...&
response_type=code
This part of my app works. Although when it comes to exchanging the Authorization token for an access token from the server, I am facing problems. The official documentation requires the URL structure to be like this:
POST https://api.bufferapp.com/1/oauth2/token.json?
client_id=...&
client_secret=...&
redirect_uri=...&
code=...&
grant_type=authorization_code
Correct me if I'm wrong, but from what I know there is no way to make a POST request from a browser, unless submitting a form. For this reason, I have decided to use the WebClient class to submit data to the server. However, no matter if I run my code on an actual device or on the Visual studio emulator I always receive the following error:
The remote server returned an error: NotFound
Does anyone have any idea what's wrong with the following code? I've spent over 5 hours across 2 days trying to solve this error, but nothing seems to be working.
The code I'm using:
WebClient wc = new WebClient();
wc.UploadStringCompleted += new UploadStringCompletedEventHandler(wc_UploadStringCompleted);
wc.UploadStringAsync(new Uri(access_token_url), "POST", GetPostParameters());
void wc_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
try
{
MessageBox.Show(e.Result);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
string GetPostParameters()
{
string data = "";
data += "client_id="+client_id + "&";
data += "client_secret=" +client_secret + "&";
data += "redirect_uri=" + redirect_uri+ "&";
data += "code=" + App.AccessToken + "&";
data += "grant_type=authorization_code";
return data;
}
Does anyone have any idea what's wrong? this is driving me crazy and it's a real shame that oauth has to be so complicated when it's such a used technology nowadays.
Thanks in advance.
Can you try URL-encoding the redirect_uri variable?

Sending a 410 Gone header, then redirecting

I've got a page that checks if a user is logged in or the file is public then pushes a PDF to the browser via Response.WriteFile.
Works great except when Google indexes a file and then we remove the file. So I'm looking at adding a 410 Gone to the Response.Status and then redirecting to our error.aspx page.
Firebug tells me that it gets a "302 Found" status code on the document page when a file is deleted. I'm expecting a 410.
Redirect code is:
Response.Status = "410 Gone";
Response.AddHeader("Location", Request.Url.ToString());
Response.Redirect("error.aspx");
Could someone please tell me what I'm getting wrong please?
Redirection is done by sending a status that indicates that the resource is available somewhere else, such as 301 Moved Permanently or 302 Found. You can't send two status codes in the same response. Either the requested resource does not exist (so you send 410) or it does exist at some other location (so you send 301 or 302 or whatever).
I don't think you should be redirecting to an error page, though, because an error message isn't a separate resource that should have its own URL. If a client requests a file and the file is gone, send a 410 Gone status with the error message as the response body — that way the error message comes back from the URL of the nonexistent file itself. A search engine will see the status code and understand that the file is gone, and a browser will show the response body to the user so he can read the error message.
If you look at the spec for 410 Gone, it states that "no forwarding address is known", so a redirect does not seem valid. You can return that same body on that response that you would from error.aspx if you want human users to see something.
The requested resource is no longer available at the server and no
forwarding address is known. This condition is expected to be
considered permanent. Clients with link editing capabilities SHOULD
delete references to the Request-URI after user approval. If the
server does not know, or has no facility to determine, whether or not
the condition is permanent, the status code 404 (Not Found) SHOULD be
used instead. This response is cacheable unless indicated otherwise.
The 410 response is primarily intended to assist the task of web
maintenance by notifying the recipient that the resource is
intentionally unavailable and that the server owners desire that
remote links to that resource be removed. Such an event is common for
limited-time, promotional services and for resources belonging to
individuals no longer working at the server's site. It is not
necessary to mark all permanently unavailable resources as "gone" or
to keep the mark for any length of time -- that is left to the
discretion of the server owner.
You can also use this way, first change your desire status.
Response.Status = "410 Gone";
Response.AddHeader("Location", Request.Url.ToString());
ScriptManager.RegisterStartupScript(this, this.GetType(), "redirectScript", "window.location.href=error.aspx", true);`
So, in that you get your desire page and status as well.
This is how I had to do a 301 moved permantently response. It should be similar
//in Global.asax.cs
protected virtual void Application_BeginRequest (Object sender, EventArgs e)
{
if(Request.Url.Host=="www.earlz.biz.tm" || Request.Url.Host=="earlz.biz.tm" || Request.Url.Host=="www.lastyearswishes.com"){
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location","http://lastyearswishes.com"+Request.Url.PathAndQuery);
CompleteRequest(); //I believe this is the missing piece in your code.
}
}
I have been solving similar issue. If the page with resource is removed from the web, I woul like to tell Google Bot 410 Gone, remove from cache, but I would like to offer an alternative similar page to the visitor.
I have solved it like this:
public ActionResult RealEstate(int id, string title)
{
...prepare the model
if (realEstateModel.Result.OfferState == OfferState.Deleted)
{
var alternativeSearchResult = PrepareAlternative(realEstateModel);
return Gone410(alternativeSearchResult, context);
}
else
return View(realEstateModel);
}
Gone410.cshtml look slike this:
#model Bla.ModelGone410
#{
Layout = null;
Html.RenderAction("Index", "Search",
new
{
type = Model.type,
Category = Model.Category,
city_id = Model.city_id,
...
});
}
and RealEstate.cshtml:
#model Bla.realEstateModel
#{
Layout = null;
}
This is realestate view...
This gives the response 410 to google bot and search alternative for the user with no redirect.

How do i catch page cannot load message?

Hi i hope someone can help,
In basic terms i am trying to stop the embedded browser, in my Windows Forms app, from navigating to the 'This program cannot display the webpage' page and instead display my own error page.
The C# application is a Web Browser embedded in my Windows Forms, its purpose is allowing the user to click on the provided buttons that navigate the browser to predefined WebService URL's. If the Service is not running on the Machine then instead of the browser saying that it was unable to load i need to to navigate to my custom page instead.
I have looked around and as yet had no luck in finding a solution apparently HttpStatusCodes are a way to go but i have no idea how to use them.
Code Snippet:
private void currentMachineToolStripMenuItem_Click(object sender, EventArgs e)
{
webBrowser1.Navigate("http://localhost:2021/wsservice/status");
}
As you can see, currently very simple program.
You can try this:
Private void WebBrowser1_NavigateError(Object sender, EventArgs e)
{
WebBrowser1.Navigate( App.Path + "\retry.htm");
}
Taken from this link -
You would need to use an HttpWebRequest and an HttpWebResponse object to do
this. Create the HttpWebRequest with the desired URL, using the
WebRequest.Create(url) method. Then use the GetResponse() method to get the
HttpWebResponse. The HttpWebResponse will have the status code returned from
the server. This will tell you if the URL exists or not. 404 indicates "Page
not Found." 200 indicates "Success." Etc.
http://msdn.microsoft.com/en-us/library/8y7x3zz2(vs.71).aspx
Also another link which might help you - http://www.vcskicks.com/check-website.php
You can check the page content for a word that indicates that the page did not load correctly
if(webBrowser1.Document.InnerHtml.Contains("error"))
You can check too the returned document url, find the resource address that webBrowser use to show error page:
if (webBrowser1.Document.Url.ToString().Contains("res://ieframe.dll/dnserrordiagoff.htm") )
...

Categories