I use the following method to retrieve something from a webservice using a HTTPWebRequest:
private void RetrieveSourceCode(Method method)
{
try
{
String url = "http://123.123.123.123:8080/";
CredentialCache myCache = new CredentialCache();
myCache.Add(new Uri(url), "Basic", new NetworkCredential("user", "pwd"));
HttpWebRequest request =(HttpWebRequest)WebRequest.Create("http://abc.abc.ch:8080/famixParser/projects/argouml/org.argouml.uml.ui.behavior.common_behavior.ActionAddSendActionSignal.doIt(java.util.Collection)");
Console.WriteLine(request.RequestUri.ToString());
request.Credentials = myCache;
request.Accept = "text/plain";
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (Exception e)
{
Console.WriteLine("exception when sending query: ");
throw e;
}
Stream resStream = response.GetResponseStream();
byte[] buf = new byte[8192];
StringBuilder sb = new StringBuilder();
string tempString = null;
int count = 0;
do
{
// fill the buffer with data
count = resStream.Read(buf, 0, buf.Length);
// make sure we read some data
if (count != 0)
{
// translate from bytes to ASCII text
tempString = Encoding.ASCII.GetString(buf, 0, count);
// continue building the string
sb.Append(tempString);
}
}
while (count > 0); // any more data to read?
String sourceCode = sb.ToString();
method.setSourceCode(sourceCode);
Console.WriteLine(sourceCode);
request.Abort();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Now I always get a 401 - Access denied exception. I don't know why, because if i use the same URL in my webbrowser, it works. Is it maybe because of the parantheses?
Please note: I changed the server address here, so its not working here, but I had to do it for confidentiality reasons.
You cache url and request url are different, I would think that means your username and password aren't being passed in the request.
String url = "http://123.123.123.123:8080/";
CredentialCache myCache = new CredentialCache();
myCache.Add(new Uri(url), "Basic", new NetworkCredential("user", "pwd"));
uses 123.123
HttpWebRequest request =(HttpWebRequest)WebRequest.Create("http://abc.abc.ch:8080/famixParser/projects/argouml/org.argouml.uml.ui.behavior.common_behavior.ActionAddSendActionSignal.doIt(java.util.Collection)");
uses abc.ch
Related
Below is the link which is https and return the JSON. but the code gets stuck on the HttpWebResponse and nothing happens. It does not go in the catch block also.
public static string GetWebSource(string URL)
{
StringBuilder sb = new StringBuilder();
if (URL != "")
{
// used to build entire input
try
{
// used on each read operation
byte[] buf = new byte[8192];
// prepare the web page we will be asking for
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create("https://www.nseindia.com/api/option-chain-indices?symbol=NIFTY");
request.ContentType = "application/json";
request.Method = "GET";
// execute the request
HttpWebResponse response = (HttpWebResponse)
request.GetResponse();
// we will read data via the response stream
Stream resStream = response.GetResponseStream();
string tempString = null;
int count = 0;
do
{
// fill the buffer with data
count = resStream.Read(buf, 0, buf.Length);
// make sure we read some data
if (count != 0)
{
// translate from bytes to ASCII text
tempString = Encoding.UTF8.GetString(buf, 0, count);
// continue building the string
sb.Append(tempString);
}
}
while (count > 0); // any more data to read?
}
catch (Exception ex)
{
}
}
// print out page source
return sb.ToString();
}
I am trying to use this C# to get oauth token from a website. But the below codes return '404 Bad Request' error. Is there anything wrong in my code? The website engineer says there should be a JSON file returned to show error details. How do I get that JSON file? What I can see is just 1 line error message in VS2012.
private void Button_Click_1(object sender, RoutedEventArgs e)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://xxxx.com/api/oauth/token");
webRequest.Method = "POST";
webRequest.AllowAutoRedirect = true;
//write the data to post request
String postData = "client_id=abc&client_secret=xxx&grant_type=client_credentials";
byte[] buffer = Encoding.Default.GetBytes(postData);
if (buffer != null)
{
webRequest.ContentLength = buffer.Length;
webRequest.GetRequestStream().Write(buffer, 0, buffer.Length);
}
HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string strResponse = reader.ReadToEnd();
I used Postman to send a request and I can get the token in its response. How should I modify my C# codes to get the token?
Can you try like this
public (string, string, string, string) GetOAuth(string CliendId, string ClientSecret, string OAuthURl)
{
using (var httpClient = new HttpClient())
{
var creds = $"client_id={CliendId}&client_secret={ClientSecret}&grant_type=client_credentials";
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var content = new StringContent(creds, Encoding.UTF8, "application/x-www-form-urlencoded");
var response = httpClient.PostAsync(OAuthURl, content).Result;
var jsonContent = response.Content.ReadAsStringAsync().Result;
var tokenObj = JsonConvert.DeserializeObject<dynamic>(jsonContent);
var access_token = tokenObj?.access_token;
var token_type = tokenObj?.token_type;
var expires_in = tokenObj?.expires_in;
var scope = tokenObj?.scope;
return (access_token, token_type, expires_in, scope);
}
}
private void HowTOUse()
{
string access_token, token_type, expires_in, scope;
(access_token, token_type, expires_in, scope) = GetOAuth("client_id", "client_secret", "oauthurl");
}
Try using like the below code hope this code will solve the problem
private void Button_Click_1(object sender, RoutedEventArgs e)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://xxxx.com/api/oauth/token");
webRequest.Method = "POST";
webRequest.AllowAutoRedirect = true;
//write the data to post request
String postData =
"client_id=abc&client_secret=xxx&grant_type=client_credentials";
//byte[] buffer = Encoding.Default.GetBytes(postData);
//add these lines
byte[] buffer = System.Text.Encoding.ASCII.GetBytes(postData);
if (buffer != null)
{
webRequest.ContentLength = buffer.Length;
webRequest.GetRequestStream().Write(buffer, 0, buffer.Length);
}
try
{
using (HttpWebResponse response =
(HttpWebResponse)webRequest.GetResponse())
{
using (Stream dataStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(dataStream);
string strResponse = reader.ReadToEnd();
TokenModel dt = JsonConvert.DeserializeObject<TokenModel>
(strResponse);
token = dt.accessToken;
//Assign json Token values from strResponse to model tok_val
tok_val.accessToken = dt.accessToken;
tok_val.expires_in = dt.expires_in;
tok_val.RefreshToken = dt.RefreshToken;
tok_val.tokenType = dt.tokenType;
}
}
}
catch (WebException wex)
{
error = "Request Issue: " + wex.Message;
}
catch (Exception ex)
{
error = "Issue: " + ex.Message;
}
I am attempting to load a page I've received from an RSS feed and I receive the following WebException:
Cannot handle redirect from HTTP/HTTPS protocols to other dissimilar ones.
with an inner exception:
Invalid URI: The hostname could not be parsed.
I wrote a code that would attempt loading the url via an HttpWebRequest. Due to some suggestions I received, when the HttpWebRequest fails I then set the AllowAutoRedirect to false and basically manually loop through the iterations of redirect until I find out what ultimately fails. Here's the code I'm using, please forgive the gratuitous Console.Write/Writeline calls:
Uri url = new Uri(val);
bool result = true;
System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);
string source = String.Empty;
Uri responseURI;
try
{
using (System.Net.WebResponse webResponse = req.GetResponse())
{
using (HttpWebResponse httpWebResponse = webResponse as HttpWebResponse)
{
responseURI = httpWebResponse.ResponseUri;
StreamReader reader;
if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
{
reader = new StreamReader(new GZipStream(httpWebResponse.GetResponseStream(), CompressionMode.Decompress));
}
else if (httpWebResponse.ContentEncoding.ToLower().Contains("deflate"))
{
reader = new StreamReader(new DeflateStream(httpWebResponse.GetResponseStream(), CompressionMode.Decompress));
}
else
{
reader = new StreamReader(httpWebResponse.GetResponseStream());
}
source = reader.ReadToEnd();
reader.Close();
}
}
req.Abort();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(source);
result = true;
}
catch (ArgumentException ae)
{
Console.WriteLine(url + "\n--\n" + ae.Message);
result = false;
}
catch (WebException we)
{
Console.WriteLine(url + "\n--\n" + we.Message);
result = false;
string urlValue = url.ToString();
try
{
bool cont = true;
int count = 0;
do
{
req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(urlValue);
req.Headers.Add("Accept-Language", "en-us,en;q=0.5");
req.AllowAutoRedirect = false;
using (System.Net.WebResponse webResponse = req.GetResponse())
{
using (HttpWebResponse httpWebResponse = webResponse as HttpWebResponse)
{
responseURI = httpWebResponse.ResponseUri;
StreamReader reader;
if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
{
reader = new StreamReader(new GZipStream(httpWebResponse.GetResponseStream(), CompressionMode.Decompress));
}
else if (httpWebResponse.ContentEncoding.ToLower().Contains("deflate"))
{
reader = new StreamReader(new DeflateStream(httpWebResponse.GetResponseStream(), CompressionMode.Decompress));
}
else
{
reader = new StreamReader(httpWebResponse.GetResponseStream());
}
source = reader.ReadToEnd();
if (string.IsNullOrEmpty(source))
{
urlValue = httpWebResponse.Headers["Location"].ToString();
count++;
reader.Close();
}
else
{
cont = false;
}
}
}
} while (cont);
}
catch (UriFormatException uriEx)
{
Console.WriteLine(urlValue + "\n--\n" + uriEx.Message + "\r\n");
result = false;
}
catch (WebException innerWE)
{
Console.WriteLine(urlValue + "\n--\n" + innerWE.Message+"\r\n");
result = false;
}
}
if (result)
Console.WriteLine("testing successful");
else
Console.WriteLine("testing unsuccessful");
Since this is currently just test code I hardcode val as http://rss.nytimes.com/c/34625/f/642557/s/3d072012/sc/38/l/0Lartsbeat0Bblogs0Bnytimes0N0C20A140C0A70C30A0Csarah0Ekane0Eplay0Eamong0Eofferings0Eat0Est0Eanns0Ewarehouse0C0Dpartner0Frss0Gemc0Frss/story01.htm
the ending url that gives the UriFormatException is: http:////www-nc.nytimes.com/2014/07/30/sarah-kane-play-among-offerings-at-st-anns-warehouse/?=_php=true&_type=blogs&_php=true&_type=blogs&_php=true&_type=blogs&_php=true&_type=blogs&_php=true&_type=blogs&_php=true&_type=blogs&_php=true&_type=blogs&partner=rss&emc=rss&_r=6&
Now I'm sure if I'm missing something or if I'm doing the looping wrong, but if I take val and just put that into a browser the page loads fine, and if I take the url that causes the exception and put it in a browser I get taken to an account login for nytimes.
I have a number of these rss feed urls that are resulting in this problem. I also have a large number of these rss feed urls that have no problem loading at all. Let me know if there is any more information needed to help resolve this. Any help with this would be greatly appreciated.
Could it be that I need to have some sort of cookie capability enabled?
You need to keep track of the cookies while doing all your requests. You can use an instance of the CookieContainer class to achieve that.
At the top of your method I made the following changes:
Uri url = new Uri(val);
bool result = true;
// keep all our cookies for the duration of our calls
var cookies = new CookieContainer();
System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);
// assign our CookieContainer to the new request
req.CookieContainer = cookies;
string source = String.Empty;
Uri responseURI;
try
{
And in the exception handler where you create a new HttpWebRequest, you do the assignment from our CookieContainer again:
do
{
req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(urlValue);
// reuse our cookies!
req.CookieContainer = cookies;
req.Headers.Add("Accept-Language", "en-us,en;q=0.5");
req.AllowAutoRedirect = false;
using (System.Net.WebResponse webResponse = req.GetResponse())
{
This makes sure that on each successive call the already present cookies are resend again in the next request. If you leave this out, no cookies are sent and therefore the site you try to visit assumes you are a fresh/new/unseen user and gives you a kind of authentication path.
If you want to store/keep cookies beyond this method you could move the cookie instance variable to a static public property so you can use all those cookies program-wide like so:
public static class Cookies
{
static readonly CookieContainer _cookies = new CookieContainer();
public static CookieContainer All
{
get
{
return _cookies;
}
}
}
And to use it in a WebRequest:
var req = (System.Net.HttpWebRequest) WebRequest.Create(url);
req.CookieContainer = Cookies.All;
I have two identical web services currently installed on the same PC for testing purposes. A request that is received by the first service, is suposed go to the second one as well. My intention was to do this using a HttpModule. I handle the request during application.BeginRequest.
public void AsyncForwardRequest(HttpRequest request)
{
try
{
// Prepare web request...
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(WSaddress);
req.Credentials = CredentialCache.DefaultCredentials;
req.Headers.Add("SOAPAction", request.Headers["SOAPAction"]);
req.ContentType = request.Headers["Content-Type"];
req.Accept = request.Headers["Accept"];
req.Method = request.HttpMethod;
// Send the data.
long posStream = request.InputStream.Position;
long len = request.InputStream.Length;
byte[] buff = new byte[len];
request.InputStream.Seek(0, SeekOrigin.Begin);
if (len < int.MaxValue && request.InputStream.Read(buff, 0, (int)len) > 0)
{
using (Stream stm = req.GetRequestStream())
{
stm.Write(buff, 0, (int)len);
}
request.InputStream.Position = posStream;
DebugOutputStream(request.InputStream);
request.InputStream.Seek(0, SeekOrigin.Begin);
IAsyncResult result = (IAsyncResult)req.BeginGetResponse(new AsyncCallback(RespCallback), req);
}
}
catch (Exception ex)
{
App.Error2(String.Format("RequestDuplicatorModule - BeginRequest; ERROR begin request: {0}", ex.Message), ex);
}
private static void RespCallback(IAsyncResult asynchronousResult)
{
try
{
// State of request is asynchronous.
var req = (HttpWebRequest)asynchronousResult.AsyncState;
WebResponse resp = (HttpWebResponse)req.EndGetResponse(asynchronousResult);
Stream responseStream = resp.GetResponseStream();
System.IO.Stream stream = responseStream;
Byte[] arr = new Byte[1024 * 100];
stream.Read(arr, 0, 1024 * 100);
if (arr.Length > 0)
{
string body = (new ASCIIEncoding()).GetString(arr);
Debug.Print(body);
}
}
catch (WebException ex)
{
App.Error2(String.Format("RequestDuplicatorModule - BeginRequest; ERROR begin request: {0}", ex.Message), ex);
}
}
This (HttpWebResponse)req.EndGetResponse(asynchronousResult) throws an exception: 500 Internal Server Error and fails. The original request goes through fine.
request.InnerStream:
...
Does this have anything to do with the web service addresses being different? In my case they're:
http://localhost/WS/service.asmx
http://localhost/WS_replicate/service.asmx
I would at least implement this, to be able to read the content of a httpwebrequest that has a status 500:
catch (WebException ex)
{
HttpWebResponse webResponse = (HttpWebResponse)ex.Response;
Stream dataStream = webResponse.GetResponseStream();
if (dataStream != null)
{
StreamReader reader = new StreamReader(dataStream);
response = reader.ReadToEnd();
}
}
Not answering your question though, i would suggest having a simple amsx that reads the request, and posts the request to the two different web services. If you need some code for that let me know.
Additional advantages would be that the asmx will be easier to support for the developer as well as the one dealing with the deployment. You could add configuration options to make the actual url's dynamic.
Was able to modify the AsyncForwardRequest method so that I can actually edit the SoapEnvelope itself:
string buffString = System.Text.UTF8Encoding.UTF8.GetString(buff);
using (Stream stm = req.GetRequestStream())
{
bool stmIsReadable = stm.CanRead; //false, stream is not readable, how to get
//around this?
//solution: read Byte Array into a String,
//modify <wsa:to>, write String back into a
//Buffer, write Buffer to Stream
buffString = buffString.Replace("http://localhost/WS/Service.asmx", WSaddress);
//write modded string to buff
buff = System.Text.UTF8Encoding.UTF8.GetBytes(buffString);
stm.Write(buff, 0, (int)buff.Length);
}
Thanks icktoofay,
I tried using HttpWebRequest and HttpWebResponse.
When I request for URL by passing the Credentials like UserName And Password.
I will get the Session Id Back in the Response.
After getting that Session Id, How to Move Further.
The authenticated user are tracked using credentials/cookies.
I'm Having the Exact Url of the File to be downloaded and credentials.
If you want to use Cookies I will. I need to read the File Data and write/save it in a Specified Location.
The code I'm using is;
string username = "";
string password = "";
string reqString = "https://xxxx.com?FileNAme=asfhasf.mro" + "?" +
"username=" + username + &password=" + password;
byte[] requestData = Encoding.UTF8.GetBytes(reqString);
string s1;
CookieContainer cc = new CookieContainer();
var request = (HttpWebRequest)WebRequest.Create(loginUri);
request.Proxy = null;
request.CookieContainer = cc;
request.Method = "POST";
HttpWebResponse ws = (HttpWebResponse)request.GetResponse();
Stream str = ws.GetResponseStream();
//ws.Cookies
//var request1 = (HttpWebRequest)WebRequest.Create(loginUri);
byte[] inBuf = new byte[100000];
int bytesToRead = (int) inBuf.Length;
int bytesRead = 0;
while (bytesToRead > 0)
{
int n = str.Read(inBuf, bytesRead,bytesToRead);
if (n==0)
break;
bytesRead += n;
bytesToRead -= n;
}
FileStream fstr = new FileStream("weather.jpg", FileMode.OpenOrCreate,
FileAccess.Write);
fstr.Write(inBuf, 0, bytesRead);
str.Close();
fstr.Close();
This is how I do it:
const string baseurl = "http://www.some......thing.com/";
CookieContainer cookie;
The first method logins to web server and gets session id:
public Method1(string user, string password) {
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseurl);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
string login = string.Format("go=&Fuser={0}&Fpass={1}", user, password);
byte[] postbuf = Encoding.ASCII.GetBytes(login);
req.ContentLength = postbuf.Length;
Stream rs = req.GetRequestStream();
rs.Write(postbuf,0,postbuf.Length);
rs.Close();
cookie = req.CookieContainer = new CookieContainer();
WebResponse resp = req.GetResponse();
resp.Close();
}
The other method gets the file from server:
string GetPage(string path) {
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(path);
req.CookieContainer = cookie;
WebResponse resp = req.GetResponse();
string t = new StreamReader(resp.GetResponseStream(), Encoding.Default).ReadToEnd();
return IsoToWin1250(t);
}
Note that I return the page as string. You would probably better return it as bytes[] to save to disk. If your jpeg files are small (they usually are not gigabyte in size), you can simply put them to memory stream, and then save to disk. It will take some 2 or 3 simple lines in C#, and not 30 lines of tough code with potential dangerous memory leaks like you provided above.
public override DownloadItems GetItemStream(string itemID, object config = null, string downloadURL = null, string filePath = null, string)
{
DownloadItems downloadItems = new DownloadItems();
try
{
if (!string.IsNullOrEmpty(filePath))
{
using (FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
{
if (!string.IsNullOrEmpty(downloadURL))
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(downloadURL);
request.Method = WebRequestMethods.Http.Get;
request.PreAuthenticate = true;
request.UseDefaultCredentials = true;
const int BUFFER_SIZE = 16 * 1024;
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
var buffer = new byte[BUFFER_SIZE];
int bytesRead;
do
{
bytesRead = responseStream.Read(buffer, 0, BUFFER_SIZE);
fileStream.Write(buffer, 0, bytesRead);
} while (bytesRead > 0);
}
}
fileStream.Close();
downloadItems.IsSuccess = true;
}
}
else
downloadItems.IsSuccess = false;
}
}
}
catch (Exception ex)
{
downloadItems.IsSuccess = false;
downloadItems.Exception = ex;
}
return downloadItems;
}