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).
Related
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
}
}
I've searched and found lots on this topic, but I'm just not getting this to work. My request returns the HTML from asmx page that displays the web method (action), but does not perform the action, which basically returns a true/false.
I'm using the same SOAP 1.1 that my method provides. And, when I test the functionality by using the "Invoke" button provided it works just fine. But I really need to call this function behind-the-scenes so I can't use the HTTP Post like this button. Any ideas?
.cs code in App_Code directory of website:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Text;
using System.Web.Caching;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
[WebService(Namespace = "http://www.xxx.org/")]
public class VacationSickPayoutLogger : System.Web.Services.WebService
{
[WebMethod]
public string RunVacationSickPayoutWS()
{
return "True";
}
}
Code from asmx file:
<%# WebService Language="C#" CodeBehind="~/App_Code/VacationSickPayoutLogger.cs" Class="VacationSickPayoutLogger" %>
Code to call web method:
protected void Page_Load(object sender, EventArgs e)
{
string soap =
#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<RunVacationSickPayoutWS xmlns=""http://www.xxx.org/"" />
</soap:Body>
</soap:Envelope>";
var _url = "http://localhost/HR/VacationSickPayoutLogger.asmx";
var _action = "\"http://www.xxx.org/RunVacationSickPayoutWS\"";
System.Xml.XmlDocument soapEnvelopeXml = CreateSoapEnvelope(soap);
HttpWebRequest webRequest = CreateWebRequest(_url, _action);
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
// begin async call to web request.
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
// suspend this thread until call is complete. You might want to
// do something usefull here like update your UI.
asyncResult.AsyncWaitHandle.WaitOne();
// get the response from the completed web request.
string soapResult;
using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
{
using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
{
soapResult = rd.ReadToEnd();
}
Response.Write(soapResult);
}
}
private static HttpWebRequest CreateWebRequest(string url, string action)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPAction", action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}
private static System.Xml.XmlDocument CreateSoapEnvelope(string soap)
{
System.Xml.XmlDocument soapEnvelop = new System.Xml.XmlDocument();
soapEnvelop.LoadXml(soap);
return soapEnvelop;
}
private static void InsertSoapEnvelopeIntoWebRequest(System.Xml.XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
}
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];
So I am trying to create a simple class which I could use to consume REST web services. However I am having some troubles with HttpWebRequest object. Here is my code:
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;
namespace RichardKnop.Utils
{
public class REST
{
public void POST(string Uri)
{
}
public void GET(string Uri)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
// Set some reasonable limits on resources used by this request
request.MaximumAutomaticRedirections = 4;
request.MaximumResponseHeadersLength = 4;
// Set credentials to use for this request.
request.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine("Content length is {0}", response.ContentLength);
Console.WriteLine("Content type is {0}", response.ContentType);
// Get the stream associated with the response.
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);
Console.WriteLine("Response stream received.");
Console.WriteLine(readStream.ReadToEnd());
response.Close();
readStream.Close();
}
}
}
However I am getting several errors - for example:
Error 4 'System.Net.HttpWebRequest' does not contain a definition for 'GetResponse' and no extension method 'GetResponse' accepting a first argument of type 'System.Net.HttpWebRequest' could be found (are you missing a using directive or an assembly reference?) C:\Users\Richard\Documents\Visual Studio 2010\Projects\RichardKnop\RichardKnop\Utils\REST.cs 31 65 RichardKnop
How is that possible that it does not contain definition of the GetResponse method when I can clearly see in the documentation that it does have a method like that? Here it is:
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse.aspx
Sorry if this is something trivial but I am new to .NET.
As far as i know Silverlight allows only asynchronous calls
try using BeginGetResponse. MSDN link