Im sending data to local website using c# console application. Function that sends data is:
public static HttpWebRequest GetRequest(String url, NameValueCollection nameValueCollection)
{
// Here we convert the nameValueCollection to POST data.
// This will only work if nameValueCollection contains some items.
var parameters = new StringBuilder();
foreach (string key in nameValueCollection.Keys)
{
parameters.AppendFormat("{0}={1}&",
HttpUtility.UrlEncode(key),
HttpUtility.UrlEncode(nameValueCollection[key]));
}
parameters.Length -= 1;
// Here we create the request and write the POST data to it.
var request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(parameters.ToString());
}
return request;
}
url and NameValueCollection are correct.
but I cant receive anything on the website.
website code is:
System.IO.StreamReader reader = new System.IO.StreamReader(HttpContext.Current.Request.InputStream);
string requestFromPost = reader.ReadToEnd();
Response.Write(requestFromPost);
I'm new to asp.net. What am I missing?
Try this.
var parameters = new StringBuilder();
foreach (string key in nameValueCollection.Keys)
{
parameters.AppendFormat("{0}={1}&",
HttpUtility.UrlEncode(key),
HttpUtility.UrlEncode(nameValueCollection[key]));
}
parameters.Length -= 1;
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
// Every so often I've seen weird issues if the user agent isn't set
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
// encode the data for transmission
byte[] bytedata = Encoding.UTF8.GetBytes(parameters.ToString());
// tell the other side how much data is coming
request.ContentLength = bytedata.Length;
using (Stream writer = request.GetRequestStream())
{
writer.Write(bytedata, 0, bytedata.Length);
}
String result = String.Empty;
using (var response = (HttpWebResponse)request.GetResponse()) {
using(StreamReader reader = new StreamReader(response.GetResponseStream())) {
result = reader.ReadToEnd(); // gets the response from the server
// output this or at least look at it.
// generally you want to send a success or failure message back.
}
}
// not sure why you were returning the request object.
// you really just want to pass the result back from your method
return result;
You probably want to wrap most of the above in a try..catch. If the post fails then it's going to throw an exception.
On the receiving end, it's a little easier. You can do things like:
String val = Request.QueryString["myparam"];
or just iterate through the query string collection.
Related
I try to getting data from google play web page with C# HttpWebRequest but when it's response I got difference result
Code:
public const string googlePlayUrl = "https://play.google.com/store/apps/details?id=";
public void GetData(string packageName) {
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(googlePlayUrl + packageName));
request.Method = WebRequestMethods.Http.Get;
request.ContentType = "text/html";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0";
request.AutomaticDecompression = DecompressionMethods.GZip;
request.BeginGetResponse((IAsyncResult asynchronousResult) =>
{
HttpWebRequest requested = (HttpWebRequest)asynchronousResult.AsyncState;
using (HttpWebResponse response = (HttpWebResponse)requested.EndGetResponse(asynchronousResult))
{
System.IO.Stream responseStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(responseStream))
{
Console.WriteLine(reader.ReadToEnd());
}
responseStream.Close();
}
}, request);
}
Request connection is fine, I got response but it's difference than when I access the web-page with browser. It's no elements that I want to use such as
div.id-app-title
span attr[itemprop="genre"]
div attr[itemprop="description"]
Not sure why, I've try to set its user-agent but it still not work or maybe I set it wrong.
Wish someone have solution for that :)
Assuming your public IP address has not been blocked by Google, you can use the synchronous method request.GetResponse() together with the Parallel.ForEach() as shown below:
public static string GetDataSync(string packageName)
{
string result = "";
Uri uri = new Uri(googlePlayUrl + packageName);
var request = HttpWebRequest.Create(uri);
var response = request.GetResponse();
var responseStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(responseStream))
{
result = (reader.ReadToEnd());
}
responseStream.Close();
return result;
}
Call the method above using Parallel.ForEach and a tread-safe collection ConcurrentDictionary to store the html string result per package:
IEnumerable<string> appPackages = new List<string>() {
"com.google.android.apps.youtube.music",
"com.netflix.mediaclient"
};
ConcurrentDictionary<string, string> results =
new ConcurrentDictionary<string, string>(Environment.ProcessorCount, appPackages.Count());
Parallel.ForEach(appPackages, (app) =>
{
results.TryAdd(app, GetDataSync(app));
});
I have website A which is done in ASP.NET and it has in default.aspx
[System.Web.Services.WebMethod]
public string GetCurrentTime(string name)
{
return "Hello " + name + Environment.NewLine + "The Current Time is: "
+ DateTime.Now.ToString();
}
May we call that method somehow from another website B using C#?
Thank you!
May we call that method somehow from another website B using C#?
Yes, you can make REQUESTS to the endpoint using C#. Either GET or POST
Simple GET request
var endPoint = "http://domain.com/default.aspx";
var webReq = (HttpWebRequest)WebRequest.Create(endPoint);
using (var response = webReq.GetResponse()) {
using (var responseStream = response.GetResponseStream()) {
var reader = new StreamReader(responseStream);
var responseString = reader.ReadToEnd();
//Do whatever with responseString
}
}
Simple POST request
var endPoint = "http://domain.com/default.aspx"
var data = "param1=hello¶m2=world"
var webReq = (HttpWebRequest)WebRequest.Create(endPoint);
webReq.Method = "POST";
var bytes = Encoding.UTF8.GetBytes(data);
webReq.ContentLength = bytes.Length;
webReq.ContentType = "application/x-www-form-urlencoded";
using (var requestStream = webReq.GetRequestStream()) {
requestStream.Write(bytes, 0, bytes.Length);
}
using (var response = webReq.GetResponse()) {
using (var responseStream = response.GetResponseStream()) {
var reader = new StreamReader(responseStream);
var responseString = reader.ReadToEnd();
//Do whatever with responseString
}
}
This is a simple way of doing it. More info at MSDN.
You can use WebClient or HttpClient on the other hand. You can find example in this post also.
Yes of course, webapi is created intentionally to be called from inside the same website, another website, and from a whatever client (console, winform, wpf, mobile apps, and so on) using c# or another language.
.Net framework has avalaible various classes for calling webapi ex. HttpWebRequest, HttpClient or external libraries ex. RestSharp.
I am writing a simple C# program to do some web request and posting data.
I understand how the basics work like how to login with password and stuff of a html form.
However I am wondering if there is a lot of input parameters (such as this question page ) like check boxes and text fields, is there any efficient method than hard-coding 20 parameters in a string and passing it in? I can read the html file parse it and scan out the input and use String builder to make such a string but I am wondering is there a more efficient method than doing that?
private HtmlAgilityPack.HtmlDocument getpage(string url ,String input)
{
try
{
Stream datastream;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
request.AllowAutoRedirect = true;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2";
request.ContentType = "application/x-www-form-urlencoded";
if (input!=null)
{
String postData = "";
request.Method = "POST";
if (input == "login")
{
postData = String.Format("username={0}&password={1}", "myusername", "mypassword");
}
else if (input == "sendMessage")
{
//THIS IS THE LONG STRING THAT I DON'T WANT TO HARD CODE
postData = String.Format("reciever={0}&sendmessage={1}", "thepersontomessage" ,this.DefaultMessage);
//I am just puting two parameters for now, there should be alot
}
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentLength = byteArray.Length;
datastream = request.GetRequestStream();
datastream.Write(byteArray, 0, byteArray.Length);
datastream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
datastream = response.GetResponseStream();
String sourceCode = "";
using (StreamReader reader = new StreamReader(datastream))
{
sourceCode = reader.ReadToEnd();
}
HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.LoadHtml(sourceCode);
this.cookies.Add(response.Cookies);
return htmlDoc;
}
catch (Exception)
{
return null;
}
Also is there a simple way to see what are the parameter values set to when I click a button on a html form within a browser (basically the post url string and parameter values that is sent) so I can hardcode those values into the Postdatastring (check boxs, texts etc)
Personally what I would do is build the parameters as a Dictionary<string,string> so that you can just do:
var parms = new Dictionary<string,string>();
parms.Add("username","fred");
You can then have a method such as:
string DictToString(Dictionary<string,string> dict)
{
StringBuilder builder = new StringBuilder();
foreach(KeyValuePair<string,string> kvp in dict) {
builder.Append(kvp.Key + "=" + kvp.Value + "&");
}
return builder.ToString();
}
You can then get the final parameter string with:
var parms_str = builder.ToString();
I'm trying to write a bit of code to login to a website. But it's not working. Please can you give me some advice. This is my a bit of code:
static void Main(string[] args)
{
CookieContainer container = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://pagehype.com/login.php");
request.Method = "POST";
request.Timeout = 10000;
request.ReadWriteTimeout = 30000;
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729) (Prevx 3.0.5)";
request.CookieContainer = container;
ASCIIEncoding encoding = new ASCIIEncoding();
string postData = "username=user&password=password&processlogin=1&return=";
byte[] data = encoding.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
Stream newStream = request.GetRequestStream();
newStream.Write(data, 0, data.Length);
newStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string htmldoc = reader.ReadToEnd();
response.Close();
Console.Write(htmldoc);
}
Many thanks,
Use http://www.fiddler2.com/fiddler2/ to view the http request sent went you login in using a browser and ensure that the request you build in code is the same.
PHP logins use PHPSESSID cookie. You'll need to capture this and pass it back in the CookieContainer. This is how the server will recognise you as an authenticated user.
The cookie is set in the Set-Cookie header in the initial response. You'll need to parse it to recreate the cookie in your container (don't forget the path (and domain?)
var setCookie = response.GetResponseHeader("Set-Cookie");
response.Close();
container = new CookieContainer();
foreach (var cookie in setCookie.Split(','))
{
var split = cookie.Split(';');
string name = split[0].Split('=')[0];
string value = split[0].Split('=')[1];
var c = new Cookie(name, value);
if (cookie.Contains(" Domain="))
c.Domain = split.Where(x => x.StartsWith(" Domain")).First().Split('=')[1];
else
{
c.Domain = ".pagehype.com";
}
if (cookie.Contains(" Path="))
c.Path = split.Where(x => x.StartsWith(" Path")).First().Split('=')[1];
container.Add(c);
}
Then add this container to your request.
I need to essentially POST some hidden fields to a page, which i need to load in the
browser window.
This is for the SagePay forms integration as per page 6:
http://www.docstoc.com/docs/10745827/Sage-Pay-Form-Protocol-and-Integration-Guidelines
I am already using WebRequest to create the POST but how do I send the 4 hidden fields they require?
Also, how do I then load the returned html into the browser; this html is from SagePay where the customer enters their credit card details?
public string SendRequest(string url, string postData)
{
var uri = new Uri(url);
var request = WebRequest.Create(uri);
var encoding = new UTF8Encoding();
var requestData = encoding.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.Timeout = (300 * 1000); //TODO: Move timeout to config
request.ContentLength = requestData.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(requestData, 0, requestData.Length);
}
var response = request.GetResponse();
string result;
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
{
result = reader.ReadToEnd();
}
return result;
}
Just add the 4 hidden fields into the postData string. This can be done on the fly in this method, or in the request.
The "hidden" aspect is only hidden in terms of the GUI in the browser.