So I have this program that fetches a page using a short link (I used Google url shortener).
To build my example I used code from Using WebClient in C# is there a way to get the URL of a site after being redirected?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyWebClient client = new MyWebClient();
client.OpenRead("http://tinyurl.com/345yj7x");
Uri uri = client.ResponseUri;
Console.WriteLine(uri.AbsoluteUri);
Console.Read();
}
}
class MyWebClient : WebClient
{
Uri _responseUri;
public Uri ResponseUri
{
get { return _responseUri; }
}
protected override WebResponse GetWebResponse(WebRequest request)
{
WebResponse response = base.GetWebResponse(request);
_responseUri = response.ResponseUri;
return response;
}
}
}
I do not understant a thing: when I do client.OpenRead("http://tinyurl.com/345yj7x"); this downloads the page that the url points to? If this method downloads the page, I need something to get me only the url, so if there's a method to get only some headers, or only the url, please let me know.
You can get the headers only using a HEAD request, like this:
var request = WebRequest.Create(sourceUri);
request.Method = "HEAD";
var response = request.GetResponse();
if (response != null) {
// You can now use response.Headers to get header info
}
Create a HttpWebRequest with the AllowAutoRedirect property set to false, then look at the Location header on the response.
var request = (HttpWebRequest) WebRequest.Create("http://tinyurl.com/345yj7x");
request.AllowAutoRedirect = false;
var response = request.GetResponse();
var location = response.Headers[HttpResponseHeader.Location];
Related
I am trying to consume RESTful service with as simple as possible C# utility. Response is given as XML and I just want to put it into string and later "pretty print it" and save it on disk. For now I am trying just to get proper response. Service is third party and it works OK, tested it many times in browser and java client. In C# utility authorization went OK and as far as I can tell I see in debugger in response object that
StatusCode OK System.Net.HttpStatusCode
and
StatusDescription "OK" string
but looks like response itself is empty? String Xml which has to hold response as String is empty (not null but empty). What do I do wrong?
Here is complete code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.IO;
using System.Net;
using System.Xml;
namespace ConsoleApplication3
{
class Program
{
public static void SetBasicAuthHeader(WebRequest request, String userName, String userPassword)
{
string authInfo = userName + ":" + userPassword;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
request.Headers["Authorization"] = "Basic " + authInfo;
}
static void Main(string[] args)
{
HttpWebRequest request = null;
HttpWebResponse response = null;
String Xml;
// Create the web request
request = WebRequest.Create("https://some.web.services.com?id='1234'¶m1='1'¶m2='2'") as HttpWebRequest;
SetBasicAuthHeader(request, "userName", "userPassword");
// Get response
response = request.GetResponse() as HttpWebResponse;
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
Xml = reader.ReadToEnd();
// Console xml output
Console.WriteLine(Xml); //see if we get the xml response
}
}
}
I've seen some weird behavior with manually using Authorization header; try this:
using System.Net; // contains HttpRequestHeader enum
public static void SetBasicAuthHeader(WebRequest request, String userName, String userPassword)
{
string authInfo = userName + ":" + userPassword;
authInfo = Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));
string authHeader = string.Format("Basic {0}", authInfo);
request.Headers[HttpRequestHeader.Authorization] = authHeader;
}
I would recommend using HttpClient what you are trying to do, your code should be something like this:
static void Main(...)
{
var token = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{user}:{pwd}"));
using(var client = new HttpClient())
{
client.DefaultHeaders.Authorization = new AuthenticationHeaderValue("Basic", token);
// here you could also use await right after GetAsync but since a Console application I use this instead
var response = client.GetAsync(url).GetAwaiter().GetResult();
// again the await could help here
var xml = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
Console.WriteLine(xml);
}
}
you could also have also gotten a Stream instead of a string by calling: response.Content.ReadAsStreamAsync().GetAwaiter().GetResult(); and from there use it as you want, if you want to read in chunks or buffering to optimize.
Hope this helps. Also take a look at this it could be useful as it contains several extensions to convert between popular formats used in REST, although I don't know for sure if it could help you here as well with xml.
Okay, so here is what I have and I am probably doing this completely wrong, but I need some more direction than what I am finding online.
I am trying to pass a URL containing login information and then pass another url in the same connection containing my XML. That's all, and I can't seem to get this to work. Please help!!
Here's my code.
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Xml;
using System.Net;
using System.IO;
using System.Configuration;
using System.Data.SqlClient;
using System.Data.Sql;
using System.Data;
using System.ComponentModel;
using System.Collections.Specialized;
namespace DataIntegration.DataSender
{
class RaveDataSender
{
static void Main(string[] args)
{
System.Uri myUri = new System.Uri(#"https://api.myloginpage.com/edc_studyservices.jsp?action=importfile&filecontents=<?xml version='1.0'?><dataprocessitems><item>someitem</item></dataprocessitems>&filename=1.xml");
System.Uri loginUri = new System.Uri(#"https://api.myloginpage.com/login.jsp?studyid=something&action=login&login=myLoginName&password=myPassword");
byte[] mybytes = Encoding.ASCII.GetBytes("https://api.myloginpage.com/edc_studyservices.jsp?action=importfile&filecontents=<?xml version='1.0'?><dataprocessitems><item>someitem</item></dataprocessitems>&filename=1.xml");
byte[] loginbytes = Encoding.ASCII.GetBytes(#"https://api.myloginpage.com/login.jsp?studyid=something&action=login&login=myLoginName&password=myPassword");
CookieAwareWebClient client = new CookieAwareWebClient();
client.UploadDataAsync(loginUri, loginbytes);
client.UploadDataAsync(myUri, mybytes);
client.Dispose();
}
public class CookieAwareWebClient : WebClient
{
private CookieContainer cookie = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = cookie;
}
return request;
}
}
}
}
EDIT this is what I ended up doing.
using (var client = new CookieAwareWebClient())
{
byte[] authresp = client.UploadData(loginUri, loginbytes);
byte[] dataRespose = client.UploadData(xmlUri, reqbytes);
string authResult = System.Text.Encoding.UTF8.GetString(authresp);
string result = System.Text.Encoding.UTF8.GetString(dataRespose);
client.Dispose();
}
I think the problem might be that you dispose the object while the asynchronous methods still running.
Hello i making a simple httpwebrequest but the response that i get is sow me the same page like if i set cookie to Deny manually in (F12).any one know how to fix it
becuse it seems like my httpwebrequest have cookies=Deny setting
I just want to send HttpWebRequest then to read the html page from HttpWebResponse,but the html page that i get from HttpWebResponse is like if i set cookie to Deny manually in (F12)browser.i did that for check and get the same page
This my code
using System;
using System.IO;
using System.Diagnostics;
using System.Text;
using System.Collections.Generic;
using HtmlAgilityPack;
using System.Net;
using System.Web;
using System.Text.RegularExpressions;
namespace BbvaBank
{
static class bBank
{
static CookieContainer _cookies = new CookieContainer();
static string loginPostUrl = "https://www.bbvanetcash.com/local_kyop/KYOPSolicitarCredenciales.html";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginPostUrl);
request.CookieContainer = new CookieContainer();
request.AllowAutoRedirect = true;
//Get the response from the server and save the cookies from the first request..
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
request.CookieContainer = _cookies;
Stream streamResponseLogin = response.GetResponseStream();
StreamReader streamReadLogin = new StreamReader(streamResponseLogin);
LoginInfo = streamReadLogin.ReadToEnd();//here i see the page
}
}
okay so I have a c# console source code I have created but it does not work how I want it to.
I need to post data to a URL the same as if I was going to input it an a browser.
url with data = localhost/test.php?DGURL=DGURL&DGUSER=DGUSER&DGPASS=DGPASS
Here is my c# script that does not do it the way I want to I want it to post the data as if I had typed it like above.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Net;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string URL = "http://localhost/test.php";
WebClient webClient = new WebClient();
NameValueCollection formData = new NameValueCollection();
formData["DGURL"] = "DGURL";
formData["DGUSER"] = "DGUSER";
formData["DGPASS"] = "DGPASS";
byte[] responseBytes = webClient.UploadValues(URL, "POST", formData);
string responsefromserver = Encoding.UTF8.GetString(responseBytes);
Console.WriteLine(responsefromserver);
webClient.Dispose();
}
}
}
I have also triead another method in c# this does now work either
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Net;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string URI = "http://localhost/test.php";
string myParameters = "DGURL=value1&DGUSER=value2&DGPASS=value3";
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "text/html";
string HtmlResult = wc.UploadString(URI, myParameters);
System.Threading.Thread.Sleep(500000000);
}
}
}
}
I have been trying to figure a way to do this in my c# console for days now
Since what you seem to want is a GET-request with querystrings and not a POST you should do it like this instead.
static void Main(string[] args)
{
var dgurl = "DGURL", user="DGUSER", pass="DGPASS";
var url = string.Format("http://localhost/test.php?DGURL={0}&DGUSER={1}&DGPASS=DGPASS", dgurl, user, pass);
using(var webClient = new WebClient())
{
var response = webClient.DownloadString(url);
Console.WriteLine(response);
}
}
I also wrapped your WebClient in a using-statement so you don't have to worry about disposing it yourself even if it would throw an exception when downloading the string.
Another thing to think about is that you might want to url-encode the parameters in the querystring using WebUtility.UrlEncode to be sure that it doesn't contain invalid chars.
How to post data to a URL using WebClient in C#: https://stackoverflow.com/a/5401597/2832321
Also note that your parameters will not appear in the URL if you post them. See: https://stackoverflow.com/a/3477374/2832321
Can anyone tell me what I've done wrong with this simple code?
When I run it it hangs on
using (Stream postStream = request.EndGetRequestStream(asynchronousResult))
If I comment out the requestState.Wait.WaitOne(); line the code executes correctly but obviously doesn't wait for the response. I'm guessing the the call to EndGetRequestStream is somehow returning me to the context of the main thread?? I'm pretty sure my code is essentially the same as the sample though (MSDN Documentation)
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Text;
namespace SBRemoteClient
{
public class JSONClient
{
public string ExecuteJSONQuery(string url, string query)
{
System.Uri uri = new Uri(url);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.Accept = "application/json";
byte[] requestBytes = Encoding.UTF8.GetBytes(query);
RequestState requestState = new RequestState(request, requestBytes);
IAsyncResult resultRequest = request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), requestState);
requestState.Wait.WaitOne();
IAsyncResult resultResponse = (IAsyncResult)request.BeginGetResponse(new AsyncCallback(GetResponseStreamCallback), requestState);
requestState.Wait.WaitOne();
return requestState.Response;
}
private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
try
{
RequestState requestState = (RequestState)asynchronousResult.AsyncState;
HttpWebRequest request = requestState.Request;
using (Stream postStream = request.EndGetRequestStream(asynchronousResult))
{
postStream.Write(requestState.RequestBytes, 0, requestState.RequestBytes.Length);
}
requestState.Wait.Set();
}
catch (Exception e) {
Console.Out.WriteLine(e);
}
}
private static void GetResponseStreamCallback(IAsyncResult asynchronousResult)
{
RequestState requestState = (RequestState)asynchronousResult.AsyncState;
HttpWebRequest request = requestState.Request;
using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult))
{
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader streamRead = new StreamReader(responseStream))
{
requestState.Response = streamRead.ReadToEnd();
requestState.Wait.Set();
}
}
}
}
}
}
couple of things:
I don't think you can re-use the same request object. i.e. you can call BeginGetRequestStream once per instance of HttpWebRequest.
if you want to perform two requests (calls to the server) you need two instances of HttpWebRequest one per request.
if you want synchronous behavior you have two options: Use the GetRespose method
or use begin/end in a synchronous way. to do so you don't need to pass a callback to the BeginGetRequestStream method (you can pass a null instead).
take the returned value from BeginGetRequestStream (IAsyncResult) and pass it to the EndGetRequestStream method:
AsyncResult resultRequest = request.BeginGetRequestStream(null, null);
Stream postStream = request.EndGetRequestStream(asynchronousResult)
EndGetRequestStream will block until the request is completed (this is bad if you are doing it from the UI, but it will still work).