I have Netduino Plus and I need it to send Http requests to my server. I'm not a guru in C#, I've never tried it before, so I copy/paste code from internet and try to make it works. But even after several hours I can't get it work.
using System;
using System.IO;
using System.Net;
using System.Text;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
namespace NetduinoPlusApplication5
{
public class Program
{
static void Main()
{
var request = WebRequest.Create("http://example.com?variable=1");
request.Method = "GET";
var result = request.GetResponse();
}
}
}
What am I doing wrong?
You are executing a GET request so I think you want to get the response body from the server. In this case you have to use :
Stream respStream = resp.GetResponseStream();
instead of simple GetResponse(). In this way, you can read on the stream the response body.
Paolo.
Related
I am trying to make a small application to get results of GitHub API to a text file.First I am trying to get data to the console.I tried many ways as well referred many documents but I couldn't find a way to fix this issues .
https://api.github.com/users/user?client_id=8763c42f48201b31115f&client_secret=4708b9aea8e35878b9748a016198b81de24352a4
Request forbidden by administrative rules. Please make sure your request has a User-Agent header (http://developer.github.com/v3/#user-agent-required). Check https://developer.github.com for other possible causes
This is the sample code I used.Can any one help me to fix the issue about the User-Agent header
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
GetGameData().Wait();
}
public static async Task<string> GetGameData()
{
var url = "https://api.github.com/users/user?client_id=8763c42f48201b31115f&client_secret=4708b9aea8e35878b9748a016198b81de24352a4";
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(url);
Console.WriteLine(client.BaseAddress);
HttpResponseMessage response = await client.GetAsync(url);
string strResult = await response.Content.ReadAsStringAsync();
Console.WriteLine(strResult);
return strResult;
}
}
}
}
For using HttpClient, Jimi's comment worked for me:
client.DefaultRequestHeaders.Add("User-Agent", #"Mozilla/5.0 (Windows NT 10; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0");
This question's example uses HttpClient, but if you want to use WebClient, see this question: Setting the User-Agent header for a WebClient request
I'm trying to develop a web API, and when I test the POST method, the body is always null. I have tried everything when sending the request:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:1748/api/SomeAPI");
req.Method = "post";;
var aaa = Encoding.Default.GetBytes("Test");
req.ContentType = "application/xml";
req.ContentLength = aaa.Length;
req.GetRequestStream().Write(aaa, 0, aaa.Length);
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
using (System.IO.StreamReader sr = new System.IO.StreamReader(res.GetResponseStream())) {
Console.WriteLine(sr.ReadToEnd());
}
I use a breakpoint, and the API is called properly, but the body member is always null:
[HttpPost]
public void Post([FromBody]String test) {
}
try
[HttpPost]
public void SomeApi()
{
var test = HttpContext.Current.Request.Form["Test"];
}
If u send correctly the value,this will work 100%
Your Content Type is set to XML so you must pass the data as XML. This means wrapping your data in <string> element.
I would recommend using RestSharp (http://restsharp.org/) for making WebAPI calls from .Net.
var client = new RestClient("http://localhost:1748/");
var request = new RestRequest("api/SomeAPI", Method.POST);
request.AddBody("Test");
var response = client.Execute(request);
Update
I have created a sample project and it works absolutely fine:
Server side:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
namespace WebApplication1.Controllers
{
public class HomeController : ApiController
{
[Route("api/TestAPI")]
[HttpPost]
public IHttpActionResult Post([FromBody]String test)
{
return Ok(string.Format("You passed {0}.", test));
}
}
}
Client side:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:1748/api/TestAPI");
req.Method = "post"; ;
var aaa = Encoding.Default.GetBytes("\"Test\"");
req.ContentType = "application/json";
req.ContentLength = aaa.Length;
req.GetRequestStream().Write(aaa, 0, aaa.Length);
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
using (System.IO.StreamReader sr = new System.IO.StreamReader(res.GetResponseStream()))
{
Console.WriteLine(sr.ReadToEnd());
}
}
}
}
After installing the WEB API service in IIS and running the console app it prints:
"You passed Test."
Please note the quotes around the response.
If you want to use XML then you need to modify the content type and data you are sending:
var aaa = Encoding.Default.GetBytes("<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">Test</string>");
The response you will get is
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">You passed Test.</string>
Both samples in the debugger will have correct value passed in the test parameter.
Two things to try, 1st, try your request using a tried and tested tool like Postman. This will eliminate any chance your request is malformed in any way. 2nd, try changing your ContentType to text/plain. It's possible the request pipeline is seeing application/xml but your request body is invalid xml which really should be a bad request but is just being serialized as null.
I'm trying to test the behavior of an "expect: 100-continue" request being handled in an IHttpModule.
What I want to do is create a request in a client with the header expect: 100-continue and send it to the server. The server will immediately return a 500. Theoretically, the payload (file) should never be sent if the server returns a 500 instead of a 100.
I'm not seeing the expected behavior. This is what I'm doing...
Here is the server code (http module):
using System;
using System.Web;
namespace WebSite
{
public class Expect100ContinueModule : IHttpModule
{
private HttpApplication httpApplication;
public void Init(HttpApplication context)
{
httpApplication = context;
context.BeginRequest += ContextBeginRequest;
}
private void ContextBeginRequest(object sender, EventArgs e)
{
var request = httpApplication.Context.Request;
var response = httpApplication.Context.Response;
if(!request.Url.AbsolutePath.StartsWith("/Upload"))
{
return;
}
response.StatusCode = 500;
response.End();
}
public void Dispose()
{
}
}
}
I'm running this in IIS 7 with the integrated pipeline.
Here is the client code:
using System.IO;
using System.Net;
namespace ConsoleClient
{
class Program
{
static void Main(string[] args)
{
var request = (HttpWebRequest)WebRequest.Create("http://localhost:83/Upload/");
request.ServicePoint.Expect100Continue = true;
request.Method = "POST";
request.ContentType = "application/octet-stream";
var buffer = File.ReadAllBytes("Test - Copy.txt");
var text = File.ReadAllText("Test - Copy.txt");
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
}
var response = (HttpWebResponse)request.GetResponse();
var x = "";
}
}
}
From what I'm seeing, the request has the file content even when the 500 is returned.
One issue I ran into is, Fiddler automatically handles expect: 100-continue by buffering the request, returning 100, and continuing with the full request.
I then tried WireShark. To get that to work, I had to capture the traffic with RawCap and read the output with WireShark. From what I can tell, this still shows the full payload on the request.
Now I have a few questions.
Is the server code actually returning the 500 first, or has a 100 already been returned before I get the BegineRequest event?
Is there a better way to write the client? I don't understand why you would write your full payload to the request stream before the request is made. The server module doesn't get the BeginRequest event until the clients Request.GetResponse() method is called.
Is there a good way to test the actual traffic on localhost?
[Update]
I couldn't find a way to test locally so I used a neighbor employees desktop to test with also. I was able to test with WireShark this way.
From what I can tell, there is no way to have the HttpWebClient do a PUT request to IIS without having the full file sent, even if an IHttpModule returns an error immediately before the file is completely uploaded.
I don't know if the issue is in the client (HttpWebClient) or the server (IIS). I don't know if using raw sockets and implementing the HTTP protocol by hand would make a difference.
If anyone has any more insight into this, please let me know.
I'd like to download some data from a forum. The page containing the data is visible only to registered users. Here's an example webpage containing user data;
http://www.bikeforums.net/member.php/227664-StackOverflow
I'd like to get the data using wget or C#. I tried logging in via Firefox, then passing the cookies file (hopefully containing the login information) to wget. That was more of a makeshift hack and not a real solution, but it still failed. How do I do this properly?
I set up an account for testing if that's helpful.
User: StackOverflow
Pass: so123
Using firebug you can easily get the POST data for the login page and use it to create a WebRequest and Login to the Forum.
The Server create the cookies for authentication and we can use this cookies in the next request on the forum page so the server can authenticate the request and return all the data.
Here I've tested a simple console application that achieves this mechanism.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Web;
using System.Net;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
CookieContainer cookieContainer = new CookieContainer();
HttpWebRequest wpost = (HttpWebRequest) HttpWebRequest.Create("http://www.bikeforums.net/login.php?do=login");
wpost.CookieContainer = cookieContainer;
wpost.Method = "POST";
string postData = "do=login&vb_login_md5password=d93bd4ce1af6a9deccaf0ea844d6c05d&vb_login_md5password_utf=d93bd4ce1af6a9deccaf0ea844d6c05d&s=&securitytoken=guest&url=%2Fmember.php%2F227664-StackOverflow&vb_login_username=StackOverflow&vb_login_password=";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
wpost.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
wpost.ContentLength = byteArray.Length;
// Get the request stream.
System.IO.Stream dataStream = wpost.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
HttpWebResponse response = (HttpWebResponse) wpost.GetResponse();
// Request
wpost = (HttpWebRequest)WebRequest.Create("http://www.bikeforums.net/member.php/227664-StackOverflow");
//Assing the cookies created on the server to the new request
wpost.CookieContainer = cookieContainer;
wpost.Method = "GET";
response = (HttpWebResponse)wpost.GetResponse();
Stream receiveStream = response.GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
//Display the result to console...
Console.WriteLine(readStream.ReadToEnd());
response.Close();
readStream.Close();
Console.Read();
}
}
}
Related: how-do-i-use-webrequest-to-access-an-ssl-encrypted-site-using-https
How to send an HTTPS GET Request in C#?
Add ?var1=data1&var2=data2 to the end of url to submit values to the page via GET:
using System.Net;
using System.IO;
string url = "https://www.example.com/scriptname.php?var1=hello";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream resStream = response.GetResponseStream();
Simple Get Request using HttpClient Class
using System.Net.Http;
class Program
{
static void Main(string[] args)
{
HttpClient httpClient = new HttpClient();
var result = httpClient.GetAsync("https://www.google.com").Result;
}
}
I prefer to use WebClient, it seems to handle SSL transparently:
http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx
Some troubleshooting help here:
https://clipperhouse.com/webclient-fiddler-and-ssl/