I'm writing a small tool in C# which will need to send and receive data to/from a website using POST and json formatting. I've never done anything like this before in C# (or any language really) so I'm struggling to find some useful information to get me started.
I've found some information on the WebRequest class in C# (specifically from here) but before I start diving into it, I wondered if this was the right tool for the job.
I've found plenty of tools to convert data into the json format but not much else, so any information would be really helpful here in case I end up down a dead end.
WebRequest and more specifically the HttpWebRequest class is a good starting point for what you want to achieve. To create the request you will use the WebRequest.Create and cast the created request to an HttpWebRequest to actually use it. You will then create your post data and send it to the stream like:
HttpWebRequest req = (HttpWebRequest)
WebRequest.Create("http://mysite.com/index.php");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
string postData = "var=value1&var2=value2";
req.ContentLength = postData.Length;
StreamWriter stOut = new
StreamWriter(req.GetRequestStream(),
System.Text.Encoding.ASCII);
stOut.Write(postData);
stOut.Close();
Similarly you can read the response back by using the GetResponse method which will allow you to read the resultant response stream and do whatever else you need to do. You can find more info on the class at:
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx
WebClient is sometimes easier to use than WebRequest. You may want to take a look at it.
For JSON deserialization you are going to want to look at the JavaScriptSerializer class.
WebClient example:
using (WebClient client = new WebClient ())
{
//manipulate request headers (optional)
client.Headers.Add (HttpRequestHeader.UserAgent, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
//execute request and read response as string to console
using (StreamReader reader = new StreamReader(client.OpenRead(targetUri)))
{
string s = reader.ReadToEnd ();
Console.WriteLine (s);
}
}
Marked as wiki in case someone wants to update the code
When it comes to POSTing data to a web site, System.Net.HttpWebRequest (the HTTP-specific implementation of WebRequest) is a perfectly decent solution. It supports SSL, async requests and a bunch of other goodies, and is well-documented on MSDN.
The payload can be anything: data in JSON format or whatever -- as long as you set the ContentType property to something the server expects and understands (most likely application/json, text/json or text/x-json), all will be fine.
One potential issue when using HttpWebRequest from a system service: since it uses the IE proxy and credential information, default behavior may be a bit strange when running as the LOCALSYSTEM user (or basically any account that doesn't log on interactively on a regular basis). Setting the Proxy and Authentication properties to Nothing (or, as you C# folks prefer to call it, null, I guess) should avoid that.
I have used WebRequest for interacting with websites. It is the right 'tool'
I can't comment on the JSON aspect of your question.
The currently highest rated answer is helpful, but it doesn't send or receive JSON.
Here is an example that uses JSON for both sending and receiving:
How to post json object in web service
And here is the StackOverflow question that helped me most to solve this problem:
Problems sending and receiving JSON between ASP.net web service and ASP.Net web client
And here is another related question:
json call with C#
To convert from instance object to json formatted string and vice-versa, try out Json.NET:
http://json.codeplex.com/
I am currently using it for a project and it's easy to learn and work with and offers some flexibility in terms of serializing and custom type converters. It also supports a LINQ syntax for querying json input.
in 3.5 there is a built-in jsonserializer. The webrequest is the right class your looking for.
A few examples:
Link
http://dev.aol.com/blog/markdeveloper/ShareFileWithNETFramework
Link
Related
I am working on a university project in which I need to get some product information out of the database of outpan.com into a string or an array of strings.
I am new to coding, that's why I am needing quite a lot of help still. Does anyone of you know how to send a request & get the answer from a c#-environment (Windows Form Application)?
The description on outpan itself (https://www.outpan.com/developers.php) says to send the call by using HTTPS in curl, but what does it practically mean? Do I need to install extra libraries?
I would be glad, if someone could help me with this problem or provide me with a tutorial on how to make these curl calls to a database starting from a c# environment.
If there are more information needed about my settings, let me know.
The Outpan API uses Basic HTTP auth, so all the request will need to have a header like:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
In the request. In order to do that with C#, you could do the following:
var request = (HttpWebRequest)WebRequest.Create("https://api.outpan.com/v1/products/0796435419035");
var encodedString = Convert.ToBase64String(Encoding.Default.GetBytes("-your-api-key-here-:"));
request.Headers["Authorization"] = "Basic " + encodedString;
var response = request.GetResponse();
For a full description of the header, check out the wiki page http://en.wikipedia.org/wiki/Basic_access_authentication. Note that the base64 encoded string can be in the form [username]:[password], but the outpan api docs ( https://www.outpan.com/developers.php ) write that they do not use the password part.
Also see: Forcing Basic Authentication in WebRequest for a nice method wrapper for this logic.
I'm doing research into web programming in ASP .NET and came across these two classes. I was wondering what might these be used for?
My first thought is that they could be used if you were setting up a proxy between the client and server, but I'm not sure if this is the main purpose or not.
Thanks
edit: classes not methods
They can indeed be used for that. This isn't specific to ASP.NET however.
You can create a HttpWebRequest object by doing:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://url.com");
And you invoke it to retrieve an HttpWebResponse:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
There's a lot of customization you can do here, but hopefully this will give you a starting point for reading data off the web.
As their names imply, these are classes to either create a request (HttpWebRequest) or create a response (HttpWebResponse).
Using HttpWebRequest you define a request to a URI using the HTTP-protocol. Whereas the HttpWebResponse class delivers you an answer of an HTTP-server providing all the information like HTTP-headers and actual body of the request.
This is an example from MSDN
HttpWebRequest HttpWReq =
(HttpWebRequest)WebRequest.Create("http://www.contoso.com");
HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse();
// Insert code that uses the response object.
HttpWResp.Close();
Consider the casting from the base-class WebRequest.
See HttpWebRequest and HttpWebResponse.
They are used for communicating with another process using the HTTP protocol.
In the context of ASP.NET, your process could use them to talk to another service. Maybe your database uses the HTTP protocol, such as CouchDB. Perhaps you have a rest service that your ASP.NET application needs to talk to.
I've been searching around now for quite a while and can't get any straight answer as to how to call a java servlet from the windows phone 7 API? I've read about 'WebClient' and 'HttpWebRequest' but the implementations seem to differ for normal C# and the windows phone.
The method (or rather empty shell) I have looks like this:
public Login(string userName, password){
string servletUrl = "http://172.12.5.35:8080/SomeService/login?u="+userName+"&p="+password;
//Somehow to call the servlet>>
}
I'm a Java coder, although the syntax is almost identical, I've been thrown in the deep end here coding for the windows phone.
Also maybe worth mentioning that the servlet returns JSON. How does one handle that in C#?
Thanks in advance for any push in the right direction!
My Attempt using HttpWebRequest:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(servletUrl);
HttpWebResponse response = (HttpWebRequest)request.BeginGetResponse();
But I see that 'BeginGetResponse()' takes 2 arguments namely AsyncCallback & object state. What are these two arguments and what would mine be in this case?
I've read about 'WebClient' and 'HttpWebRequest' but the implementations seem to differ for normal C# and the windows phone.
Well, it doesn't support the synchronous API, that's all. There are lots of aspects of the WP7 API (and Silverlight in general) which are subsets of the full desktop framework. You need to think asynchronously - you'll start making the request, with a callback to fire when you get a response.
Note that this has nothing to do with the implementation of the web server you're talking to. You'd write the same code whether you're talking to a Java servlet, a Rails app, whatever.
Also maybe worth mentioning that the servlet returns JSON. How does one handle that in C#?
Personally I like Json.NET and have used that successfully on Windows Phone 7.
Here is the sample code which makes a web request to get JSON data
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(new Uri("http://api.twitter.com/1/statuses/public_timeline.json", UriKind.Absolute));
and the DownloadStringCompleted handler is,
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var jsonResponse= e.Result; // To check whether the json response is obtained or not
var jsonData = JsonConvert.DeserializeObject<SomeObject>(e.Result);
}
In the above code, SomeObject is the Class to which you want to convert the JSON data to.
Additionally, paste your json URL or json Data in this link to generate the suitable class for you.
I'm narrowing in on an underlying problem related to two prior questions.
Basically, I've got a URL that when I fetch it manually (paste it into browser) works just fine, but when I run through some code (using the HttpWebRequest) has a different result.
The URL (example):
http://208.106.250.207:8192/announce?info_hash=-%CA8%C1%C9rDb%ADL%ED%B4%2A%15i%80Z%B8%F%C&peer_id=01234567890123456789&port=6881&uploaded=0&downloaded=0&left=0&compact=0&no_peer_id=0&event=started
The code:
String uri = BuildURI(); //Returns the above URL
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
req.Proxy = new WebProxy();
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
... Parse the result (which is an error message from the server claiming the url is incorrect) ...
So, how can I GET from a server given a URL? I'm obviously doing something wrong here, but can't tell what.
Either a fix for my code, or an alternative approach that actually works would be fine. I'm not wed at all to the HttpWebRequest method.
I recommend you use Fiddler to trace both the "paste in web browser" call and the HttpWebRequest call.
Once traced you will be able to see any differences between them, whether they are differences in the request url, in the form headers, etc, etc.
It may actually be worth pasting the raw requests from both (obtained from Fiddler) here, if you can't see anything obvious.
Well, the only they might differ is in the HTTP headers that get transmitted. In particular the User-Agent.
Also, why are you using a WebProxy? That is not really necessary and it most likely is not used by your browser.
The rest of your code is fine.. Just make sure you set up the HTTP headers correctly. Check this link out:
I would suggest that you get yourself a copy of WireShark and examine the communication that happens between your browser and the server that you are trying to access. Doing so will be rather trivial using WireShark and it will show you the exact HTTP message that is being sent from the browser.
Then take a look at the communication that goes on between your C# application and the server (again using WireShark) and then compare the two to find out what exactly is different.
If the communication is a pure HTTP GET method (i.e. there is no HTTP message body involved), and the URL is correct then the only two things I could think of are:
make sure that your are send the right protocol (i.e. HTTP/1.0 or HTTP/1.1 or whatever it is that you should be sending)
make sure that you are sending all required HTTP headers correctly, and obviously that you are not sending any HTTP headers that you shouldn't be sending.
There could be something wrong with the URL. Instead of using a string, it's usually better to use an instance of System.Uri:
String url = BuildURI(); //Returns the above URL
Uri uri = new Uri(url);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
req.Proxy = new WebProxy();
using (WebResponse resp = req.GetResponse()) {
using (Stream stream = resp.GetResponseStream()) {
// whatever
}
}
I think you need to see exactly what's flowing to your server in the HTTP request. Does sound likely that the headers are interestingly different.
You can introduce a some kind of debugging proxy between your request and the server (for example RAD has such a capability in the box).
I am using xml.net in web application
When I try load xml through an http internet url using:
xmlDoc.Load("http://....")
i get an error:"connected host has failed to respond"
Anyone knows the fix for this?
Thanks
Connected Host has failed to respond is because you've not go the uri correct or you're not allowed to access it, or it's not responding to you, or it's down. http doesn't really care what it transmits.
It probably means exactly what it says: the web server responsible for requests at the URL you specify isn't sending back responses. Something's going wrong on the web server, and if so, you can't do anything about someone's web server out there in the cloud not functioning properly.
You can, however, accept the fact that not every URL will work, and that you'll have to catch the Exception that the XmlDocument or XDocument is throwing. It's reasonable to expect that this scenario may occur. Thus, you need to programming defensively and by including the appropriate exception handling to handle such cases.
EDIT: So you can access it from outside the .NET framework eh? Perhaps try using an HTTP debugger, like Fiddler, and compare the request your XML document object makes to the request your browser makes. What header fields are different? Is there a header that the browser includes that the XML document object doesn't? Or are there different header values between the two, that may be causing the .NET request not to be responded to? Go figure.
If the page is accessible through a web browser but not through the load method it sounds as like the method isn't making a proper HTTP Request to the web server for the page wanted.
You can try using an HTTPWebRequest with a standard GET method to make a proper HTTP request for the webpage. You can then pass the response to the XMLDocument.Load method as a stream and it should then load up fine.
HTTPWebRequest Class MSDN.com
Try making a WebRequest to the url and set its UserAgent property to something like "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)" . If it works load the text you get in the xmldoc.
I tried loading the xml using .Net HttpWebRequest and also tried setting the userAgent property.
But its still giving me the error message:
"Unable to connect to the remote server"
The xml is however accesible through the browser.
Here is the code:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.UserAgent ="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)";
string result = string.Empty;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Read the whole contents and return as a string
result = reader.ReadToEnd();
}
Thanks.
Is there any proxy being used by your browser?
just try telnet to see if you are able to connect to the web server by an application other than the browser.
so if you are using a url like http://www.xmlserver.com/file.xml then try the following in command prompt:
telnet xmlserver.com 80
A big difference between your request and a browser request could be bridged with the following line:
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";