I want to create a simple Windows service in C# that calls an API REST resource periodically.
The resource has a path parameter in its URL, and the variable I want to send has slashes "/".
How cant I make the call without it looking for the worng resource because of the slash?
This is my code:
httpWebRequest = (HttpWebRequest) WebRequest.Create(URI + Param); //Param : "F51D0_TX_PULSE_300_009/IDX2" and URI : "http://bla.net:8080/meter/"
httpWebRequest.ContentType = ContentType;
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("KeyId", Key);
httpWebRequest.Timeout = m_TimeOutForecast;
httpWebRequest.Proxy = Proxy;
using(var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) {
streamWriter.Write(bodyRequest);
streamWriter.Flush();
streamWriter.Close();
}
using(httpResponse = (HttpWebResponse) httpWebRequest.GetResponse()) {
if (httpResponse.StatusCode == HttpStatusCode.OK) {
using(StreamReader reader = new StreamReader(httpResponse.GetResponseStream())) {
responseFromAPI = reader.ReadToEnd();
}
}
}
I am translating a JSON API into C# Methods, and I encountered a Problem where the JSON RPC API (POST) says
All other methods require the result from authentication ( = sessionId), either per pathparameter
;jsessionid=644AFBF2C1B592B68C6B04938BD26965
or per cookie (RequestHeader)
JSESSIONID=644AFBF2C1B592B68C6B04938BD26965
My current WebRequest Method:
private async static Task<string> SendJsonAndWait(string json, string url, string sessionId) {
string result;
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using(StreamWriter streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync())) {
await streamWriter.WriteAsync(json);
streamWriter.Flush();
streamWriter.Close();
}
HttpWebResponse httpResponse = (HttpWebResponse)await httpWebRequest.GetResponseAsync();
Stream responseStream = httpResponse.GetResponseStream();
if(responseStream == null)
throw new Exception("Response Stream was null!");
using(StreamReader streamReader = new StreamReader(responseStream)) {
result = await streamReader.ReadToEndAsync();
}
return result;
}
How do I add the JSESSIONID Parameter to my WebRequest? I am not very familiar with WebRequests, please explain briefly!
Thank you!
Use Cookies.
Your Case would look like this;
private async static Task<string> SendJsonAndWait(string json, string url, string sessionId) {
Uri uri = new Uri(url);
string result;
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
//Add the JSESSIONID Cookie
if(httpWebRequest.CookieContainer == null)
httpWebRequest.CookieContainer = new CookieContainer();
if(!string.IsNullOrWhiteSpace(sessionId))
httpWebRequest.CookieContainer.Add(new Cookie("JSESSIONID", sessionId, "/", uri.Host));
using(StreamWriter streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync())) {
await streamWriter.WriteAsync(json);
streamWriter.Flush();
streamWriter.Close();
}
HttpWebResponse httpResponse = (HttpWebResponse)await httpWebRequest.GetResponseAsync();
Stream responseStream = httpResponse.GetResponseStream();
if(responseStream == null)
throw new Exception("Response Stream was null!");
using(StreamReader streamReader = new StreamReader(responseStream)) {
result = await streamReader.ReadToEndAsync();
}
return result;
}
You can add the token directly to your URL :
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create($"{url}?jsessionid={sessionId}");
Or in the headers :
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create({url);
httpWebRequest.Headers["JSESSIONID"] = sessionId;
My remote server is throwing a web exception as bad request. But I know there is more information included in the error than what I get. If I look at the details from the exception it does not list the actual content of the response. I can see the content-type, content-length and content-encoding only. If I run this same message through another library (such as restsharp) I will see detailed exception information from the remote server. How can I get more details from the response since I know the remote server is sending them?
static string getXMLString(string xmlContent, string url)
{
//string Url;
string sResult;
//Url = ConfigurationManager.AppSettings["UserURl"] + url;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/xml";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(xmlContent);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
sResult = result;
}
}
return sResult;
}
EDIT : Have you tried with a simple try-catch to see if you can get more details ?
try
{
var response = (HttpWebResponse)(request.GetResponse());
}
catch(Exception ex)
{
var response = (HttpWebResponse)ex.Response;
}
In my recherches in an answer for you, I noticed that in code there was something about encoding, that you didn't specified. Look here for exemple with such code.
var encoding = ASCIIEncoding.ASCII;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
}
Or here, in the doc, also.
// Creates an HttpWebRequest with the specified URL.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
// Sends the HttpWebRequest and waits for the response.
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
// Gets the stream associated with the response.
Stream receiveStream = myHttpWebResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader( receiveStream, encode );
Console.WriteLine("\r\nResponse stream received.");
Have you tried with such ?
I have a tika server open on my PC, and I need to send it a request with a string parameter which is a path for a file I want tika to process. The code I have so far is:
private void getFromServer(string fileName)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:9998/rmeta");
httpWebRequest.Accept = "application/json";
httpWebRequest.Method = "PUT";
httpWebRequest.KeepAlive = true;
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string postData = #"C:\Users\######\Downloads\elasticsearch\elasticsearch-1.7.1.zip";
byte[] byteArray = Encoding.ASCII.GetBytes(postData);
string json = postData;
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
//Now you have your response.
//or false depending on information in the response
console.write(responseText);
}
}
The thing is, the server gets the request, but it returns the string I sent it instead of the contents of the file in question, and I know it can work because I sent it the same request using a cURL command and it worked. Any ideas what I'm doing wrong?
PS the hashtags are instead of my username
I a newbie at windows 8 phone development. I want to send an aync HTTP POST Request to a PHP web service with some headers and XML in the request body.
Also, I want to read the response sent back by the PHP web service.
Please guide me, how can I achieve the above two stated things.
what I have tried until now i am giving below
// Main begins program execution.
public static void SendRequest()
{
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("http://mytestserver.com/Test.php");
webRequest.Method = "POST";
webRequest.ContentType = "text/xml";
webRequest.Headers["SOURCE"] = "WinApp";
var response = await httpRequest(webRequest);
}
public static async Task<string> httpRequest(HttpWebRequest request)
{
string received;
using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)))
{
using (var responseStream = response.GetResponseStream())
{
using (var sr = new StreamReader(responseStream))
{
received = await sr.ReadToEndAsync();
MessageBox.Show(received.ToString());
}
}
}
return received;
}
I am able to send the request using the above code. I just need to know that how I can send the XML in the request body to my web service.
For Set a file, and receive a server Response, I use that for sending .csv files:
First I initialize a POST Request:
/// <summary>
/// Initialize the POST HTTP request.
/// </summary>
public void SentPostReport()
{
string url = "http://MyUrlPerso.com/";
Uri uri = new Uri(url);
// Create a boundary for HTTP request.
Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.ContentType = "multipart/form-data; boundary=" + Boundary;
request.Method = "POST";
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), est);
allDone.WaitOne();
}
After initialized Request, I send the differents parts of my files (headers + content + footer).
/// <summary>
/// Send a File with initialized request.
/// </summary>
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
string contentType = "binary";
string myFileContent = "one;two;three;four;five;"; // CSV content.
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream memStream = request.EndGetRequestStream(asynchronousResult);
byte[] boundarybytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + Boundary + "\r\n");
memStream.Write(boundarybytes, 0, boundarybytes.Length);
// Send headers.
string headerTemplate = "Content-Disposition: form-data; ";
headerTemplate += "name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: " + contentType + "\r\n\r\n";
string fileName = "MyFileName.csv";
string header = string.Format(headerTemplate, "file", fileName);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
byte[] contentbytes = System.Text.Encoding.UTF8.GetBytes(myFileContent);
// send the content of the file.
memStream.Write(contentbytes, 0, contentbytes.Length);
// Send last boudary of the file ( the footer) for specify post request is finish.
byte[] boundarybytesend = System.Text.Encoding.UTF8.GetBytes("\r\n--" + Boundary + "--\r\n");
memStream.Write(boundarybytesend, 0, boundarybytesend.Length);
memStream.Flush();
memStream.Close();
allDone.Set();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
And, Finnaly, I get The response server response, indicate the file is transmetted.
/// <summary>
/// Get the Response server.
/// </summary>
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
try
{
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd(); // this is a response server.
// Close the stream object
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse
response.Close();
}
catch (Exception ex)
{
// error.
}
}
This sample works on Windows Phone 7 and Windows Phone 8.
This is for send a .csv content. You can adapt this code for send Xml content.
Replace just
string myFileContent = "one;two;three;four;five;"; // CSV content.
string fileName = "MyFileName.csv";
by your XML
string myFileContent = "<xml><xmlnode></xmlnode></xml>"; // XML content.
string fileName = "MyFileName.xml";
If all you're looking to do is take XML you've already generated and add it to your existing request as content, you'll need to be able to write to the request stream. I don't particularly care for the stock model of getting the request stream, so I'd recommend the following extension to make your life a little easier:
public static class Extensions
{
public static System.Threading.Tasks.Task<System.IO.Stream> GetRequestStreamAsync(this System.Net.HttpWebRequest wr)
{
if (wr.ContentLength < 0)
{
throw new InvalidOperationException("The ContentLength property of the HttpWebRequest must first be set to the length of the content to be written to the stream.");
}
var tcs = new System.Threading.Tasks.TaskCompletionSource<System.IO.Stream>();
wr.BeginGetRequestStream((result) =>
{
var source = (System.Net.HttpWebRequest)result.AsyncState;
tcs.TrySetResult(source.EndGetRequestStream(result));
}, wr);
return tcs.Task;
}
}
From here, augment your SendRequest method:
public static void SendRequest(string myXml)
{
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("http://mytestserver.com/Test.php");
webRequest.Method = "POST";
webRequest.Headers["SOURCE"] = "WinApp";
// Might not hurt to specify encoding here
webRequest.ContentType = "text/xml; charset=utf-8";
// ContentLength must be set before a stream may be acquired
byte[] content = System.Text.Encoding.UTF8.GetBytes(myXml);
webRequest.ContentLength = content.Length;
var reqStream = await webRequest.GetRequestStreamAsync();
reqStream.Write(content, 0, content.Length);
var response = await httpRequest(webRequest);
}
If the service you're trying to reach is a SOAP service, you could simplify this a bit more by having the IDE generate a client class for you. For more information on how to do that, check out this MSDN article. However, if the service does not have a Web Service Definition Language (WSDL) document, this approach will not be able to assist you.
You can use the HTTP Client libraries in Windows Phone 8 and use the client in the same way that Windows 8.
First, get the HTTP Client Libraries from Nuget.
And now, to perform a POST call
HttpClient client = new HttpClient();
HttpContent httpContent = new StringContent("my content: xml, json or whatever");
httpContent.Headers.Add("name", "value");
HttpResponseMessage response = await client.PostAsync("uri", httpContent);
if (response.IsSuccessStatusCode)
{
// DO SOMETHING
}
i hope this helps you :)
I have solved the problem in some other way..
class HTTPReqRes
{
private static HttpWebRequest webRequest;
public static void SendRequest()
{
webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("https://www.mydomain.com");
webRequest.Method = "PUT";
webRequest.ContentType = "text/xml; charset=utf-8";
webRequest.Headers["Header1"] = "Header1Value";
String myXml = "<Roottag><info>test</info></Roottag>";
// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(myXml);
webRequest.ContentLength = byteArray.Length;
// start the asynchronous operation
webRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), webRequest);
//webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest);
}
private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
String myXml = <Roottag><info>test</info></Roottag>";
// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(myXml);
// Write to the request stream.
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
System.Diagnostics.Debug.WriteLine(responseString);
// Close the stream object
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse
response.Close();
}
}
This perfectly solves my problem, send an XML within the HTTP Request and in Response receive the XML from the web service.
I recommend using the RestSharp library. You can find a sample request here.
This is what I used. It's really simple, add WindowsPhonePostClient.dll to your References (if you can't, try unblock the file first by properties->unblock), then use this code:
private void Post(string YourUsername, string Password)
{
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("User", YourUsername);
parameters.Add("Password", Password);
PostClient proxy = new PostClient(parameters);
proxy.DownloadStringCompleted += proxy_UploadDownloadStringCompleted;
proxy.DownloadStringAsync(new Uri("http://mytestserver.com/Test.php",UriKind.Absolute));
}
private void proxy_UploadDownloadStringCompleted(object sender,WindowsPhonePostClient.DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
MessageBox.Show(e.Result.ToString());
}
You need to create a reference to the webservice wsdl or you could try to do it manually as detailed here:
https://stackoverflow.com/a/1609427/2638872
//The below code worked for me. I receive xml response back.
private void SendDataUsingHttps()
{
WebRequest req = null;
WebResponse rsp = null;
string fileName = #"C:\Test\WPC\InvoiceXMLs\123File.xml"; string uri = "https://service.XYZ.com/service/transaction/cxml.asp";
try
{
if ((!string.IsNullOrEmpty(uri)) && (!string.IsNullOrEmpty(fileName)))
{
req = WebRequest.Create(uri);
//req.Proxy = WebProxy.GetDefaultProxy(); // Enable if using proxy
req.Method = "POST"; // Post method
req.ContentType = "text/xml"; // content type
// Wrap the request stream with a text-based writer
StreamWriter writer = new StreamWriter(req.GetRequestStream());
// Write the XML text into the stream
StreamReader reader = new StreamReader(file);
string ret = reader.ReadToEnd();
reader.Close();
writer.WriteLine(ret);
writer.Close();
// Send the data to the webserver
rsp = req.GetResponse();
HttpWebResponse hwrsp = (HttpWebResponse)rsp;
Stream streamResponse = hwrsp.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
rsp.Close();
}
}
catch (WebException webEx) { }
catch (Exception ex) { }
finally
{
if (req != null) req.GetRequestStream().Close();
if (rsp != null) rsp.GetResponseStream().Close();
}
}