HttpWebRequest Vs HttpClient - c#

I have a chunk of code that works using a HttpWebRequest and HttpWebResponse but I'd like to convert it to use HttpClient and HttpResponseMessage.
This is the chunk of code that works...
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceReq);
request.Method = "POST";
request.ContentType = "text/xml";
string xml = #"<?xml version=""1.0""?><root><login><user>flibble</user>" +
#"<pwd></pwd></login></root>";
request.ContentLength = xml.Length;
using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
{
dataStream.Write(xml);
dataStream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
And this is the code that I'd like to replace it with, if only I could get it working.
/// <summary>
/// Validate the user credentials held as member variables
/// </summary>
/// <returns>True if the user credentials are valid, else false</returns>
public bool ValidateUser()
{
bool valid = false;
try
{
// Create the XML to be passed as the request
XElement root = BuildRequestXML("LOGON");
// Add the action to the service address
Uri serviceReq = new Uri(m_ServiceAddress + "?obj=LOGON");
// Create the client for the request to be sent from
using (HttpClient client = new HttpClient())
{
// Initalise a response object
HttpResponseMessage response = null;
// Create a content object for the request
HttpContent content = HttpContentExtensions.
CreateDataContract<XElement>(root);
// Make the request and retrieve the response
response = client.Post(serviceReq, content);
// Throw an exception if the response is not a 200 level response
response.EnsureStatusIsSuccessful();
// Retrieve the content of the response for processing
response.Content.LoadIntoBuffer();
// TODO: parse the response string for the required data
XElement retElement = response.Content.ReadAsXElement();
}
}
catch (Exception ex)
{
Log.WriteLine(Category.Serious,
"Unable to validate the Credentials", ex);
valid = false;
m_uid = string.Empty;
}
return valid;
}
I think the problem is creating the content object and the XML isn't being attached correctly (maybe).

The HttpClient.Post method has an overload that takes a contentType parameter, try this:
// Make the request and retrieve the response
response = client.Post(serviceReq, "text/xml", content);

I'd love to know the reason why the one approach doesn't work and the other does but I just don't have the time for any more digging. {:o(
Anyway, here's what I found.
A failure occurs when the content of the request is created using the following
HttpContent content = HttpContentExtensions.Create(root, Encoding.UTF8, "text/xml");
But it works correctly when you create the content like this...
HttpContent content = HttpContent.Create(root.ToString(), Encoding.UTF8, "text/xml");
The final working function is this:
/// <summary>
/// Validate the user credentials held as member variables
/// </summary>
/// <returns>True if the user credentials are valid, else false</returns>
public bool ValidateUser()
{
bool valid = false;
try
{
// Create the XML to be passed as the request
XElement root = BuildRequestXML("LOGON");
// Add the action to the service address
Uri serviceReq = new Uri(m_ServiceAddress + "?obj=LOGON");
// Create the client for the request to be sent from
using (HttpClient client = new HttpClient())
{
// Initalise a response object
HttpResponseMessage response = null;
#if DEBUG
// Force the request to use fiddler
client.TransportSettings.Proxy = new WebProxy("127.0.0.1", 8888);
#endif
// Create a content object for the request
HttpContent content = HttpContent.Create(root.ToString(), Encoding.UTF8, "text/xml");
// Make the request and retrieve the response
response = client.Post(serviceReq, content);
// Throw an exception if the response is not a 200 level response
response.EnsureStatusIsSuccessful();
// Retrieve the content of the response for processing
response.Content.LoadIntoBuffer();
// TODO: parse the response string for the required data
XElement retElement = response.Content.ReadAsXElement();
}
}
catch (Exception ex)
{
Log.WriteLine(Category.Serious, "Unable to validate the user credentials", ex);
valid = false;
m_uid = string.Empty;
}
return valid;
}
Thanks.

Related

Two consecutive httpwebRequests in c#

Is it possible to make two consecutive web requests in c#? So make the inital request and then make a request from that response. I am doing this to fill out two consecutive forms in a c# program.
string postdata = "param1=...&param2=..."
var data1 = Encoding.ASCII.GetBytes(postdata);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data1.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data1, 0, data1.Length);
}
var response = (HttpWebResponse)request.GetResponse();
So if this is my first form how would I then go and fill out the second form that the completion of this form should lead to?
This is a (very) stripped down version of some code using HttpWebRequest that can send a request either via parameters or content but assumes either (or both) are objects passed in. E.g., if you need to send parameters like login and password usage would look like;
var response = HttpUtilities.Post("http://www.someurl.com/", new { login = "user", password = "1234");
// check response data + codes, etc...
var secondResponse = HttpUtilities.Post("http://www.someurl.com/page2", new { data = "stuff" });
The code below won't necessarily compile as I had to strip it down manually and is untested in its current form but it gives a very good idea of what's needed to check the response, debug, etc.;
namespace Helpers.Web
{
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Cache;
using System.Net.Http;
using System.Reflection;
using System.Web;
using Newtonsoft.Json;
using NLog;
public class HttpUtilities
{
#region NLog instance
/// <summary>
/// The single instance of an NLog LogManager for this class.
/// </summary>
private static Logger _logger = LogManager.GetCurrentClassLogger();
#endregion
#region Public Methods
public static TResponse Post<TResponse, TContent>(string uri, object parameters = null, TContent content = null)
where TContent : class
{
return GetResponse<TResponse, TContent>(uri, SerializeToQueryString(parameters),
content, HttpMethod.Post);
}
public static HttpWebResponse GetResponse<TContent>(string uri,
string parameters,
TContent content,
HttpMethod method)
where TContent : class
{
// build the full URL if parameters have been specified
if (!string.IsNullOrEmpty(parameters))
{
uri += "?" + parameters;
}
// make the request and send back the results
HttpWebRequest webRequest = BuildWebRequest(uri, content, method);
return GetWebResponse(uri, webRequest);
}
#endregion
#region Private Methods
private static HttpWebRequest BuildWebRequest<TContent>(string uri, TContent content, HttpMethod method)
where TContent : class
{
// get the request details
_logger.Trace("Building request for [{0}]", uri);
// set the web request details
_logger.Trace("Setting request header details...");
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Method = method.ToString();
webRequest.ContentType = "application/json";
webRequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
// do we have content to insert
string serializedContent = string.Empty;
if (content != null)
{
JsonSerializerSettings jsonSettings = new JsonSerializerSettings
{
// ignore the self referencing nature of EntityFramework objects and skip
// over the self references when serializing
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
// serialize the object as json and convert it into bytes we can
// inject into the content stream of the request.
serializedContent = JsonConvert.SerializeObject(content, jsonSettings);
UTF8Encoding encoding = new UTF8Encoding();
byte[] byteContent = encoding.GetBytes(serializedContent);
webRequest.ContentLength = byteContent.Length;
// write the content
// NOTE: the act of writing out the data actually sends the request!
_logger.Trace("Sending request and getting response from [{0}]", uri);
using (var contentStream = webRequest.GetRequestStream())
{
contentStream.Write(byteContent, 0, byteContent.Length);
}
_logger.Trace("Injected content into request to [{0}]. Content: {1}", uri, serializedContent);
}
else
{
// if there's no content then we haven't actually sent the request yet. However we still
// need to set the header details.
webRequest.ContentLength = 0;
_logger.Trace("Sending request and getting response from [{0}]", uri);
}
return webRequest;
}
private static HttpWebResponse GetWebResponse(string uri, HttpWebRequest webRequest)
{
HttpWebResponse response;
try
{
_logger.Debug("Sending [{0}] request to [{1}]...", webRequest.Method, webRequest.RequestUri.AbsoluteUri);
response = (HttpWebResponse)webRequest.GetResponse();
}
catch (WebException wex)
{
// we might still have response information on the request
// if this is so, then extract it and log it as we'll need to
// find out what the server actually replied with in order to debug
// what went on
_logger.Error(wex, "There was a problem getting a response from the server");
if (wex.Response != null)
{
try
{
// NOTE: this can be caused by the server returning a YSOD. You can see the formatted result
// in debug mode by using the HTML visualizer when looking at the content of the
// wResponseContent variable.
_logger.Debug("Attempting to extract server response details from WebException...");
using (Stream wResponseStream = wex.Response.GetResponseStream())
{
if (wResponseStream != null)
{
using (StreamReader wStreamReader = new StreamReader(wResponseStream))
{
string wResponseContent = wStreamReader.ReadToEnd();
_logger.Debug(wex, "Received fault response from [{0}]. Response: {1}",
uri, wResponseContent);
}
}
}
}
catch (Exception eex)
{
// there was an issue trying to get the response content from the original error.
// There's nothing more we can do except log this exception and rethrow the
// original.
_logger.Fatal(eex, "There was a problem getting response details from a WebException raised from the server");
throw;
}
}
else
{
_logger.Debug("No response data present in the exception.");
}
throw;
}
catch (Exception ex)
{
_logger.Error(ex, "There was a problem getting a response from [{0}]", uri);
throw;
}
return response;
}
private static string SerializeToQueryString(object parameters)
{
// if we weren't given anything then there's nothing we can do
if (parameters == null)
{
return string.Empty;
}
if (parameters is string)
{
return parameters as string;
}
// iterate over the parameter properties and build the query string
Type type = parameters.GetType();
BindingFlags flags = BindingFlags.Instance
| BindingFlags.GetProperty
| BindingFlags.Public;
if (type.IsInterface)
{
// if the type is an interface, only get the interface's members
flags |= BindingFlags.FlattenHierarchy;
}
PropertyInfo[] properties = type.GetProperties(flags);
List<string> urlParameters = new List<string>();
foreach (PropertyInfo prop in properties)
{
// convert the value to a string first so that we can make it safe
// to put into the URL
_logger.Trace("Getting value from {0}.{1} [{2}]", type.FullName, prop.Name, prop.PropertyType.FullName);
object rawValue = prop.GetValue(parameters, null);
string propertyValue = string.Empty;
if (rawValue != null)
{
propertyValue = rawValue.ToString();
}
urlParameters.Add(string.Format("{0}={1}", prop.Name, HttpUtility.UrlEncode(propertyValue)));
}
return string.Join("&", urlParameters.ToArray());
}
#endregion
}
}

How to make HttpClient ignore Content-Length header

I am using HttpClient to communicate with a server which I don't have access to. Sometimes the JSON response from the server is truncated.
The problem occurs when the Content-Length header is smaller than what it should be (8192 vs. 8329). It seems like a bug on the server which gives a smaller Content-Length header than the actual size of the response body. If I use Google Chrome instead of HttpClient, the response is always complete.
Therefore, I want to make HttpClient to ignore the wrong Content-Length header and read to the end of the response. Is it possible to do that? Any other solution is well appreciated. Thank you!
This is the code of my HttpClient:
var client = new HttpClient();
client.BaseAddress = new Uri(c_serverBaseAddress);
HttpResponseMessage response = null;
try
{
response = await client.GetAsync(c_serverEventApiAddress + "?location=" + locationName);
}
catch (Exception e)
{
// Do something
}
var json = response.Content.ReadAsStringAsync().Result;
var obj = JsonConvert.DeserializeObject<JObject>(json); // The EXCEPTION occurs HERE!!! Because the json is truncated!
EDIT 1:
If I use HttpWebRequest, it can read to the end of the JSON response completely without any truncation. However, I would like to use HttpClient since it has better async/await.
This is the code using HttpWebRequest:
var url = c_serverBaseAddress + c_serverEventApiAddress + "?location=" + "Saskatchewan";
var request = (HttpWebRequest)WebRequest.Create(url);
request.ProtocolVersion = HttpVersion.Version10;
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
var response = (HttpWebResponse)request.GetResponse();
StringBuilder stringBuilder = new StringBuilder();
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string line;
while ((line = reader.ReadLine()) != null)
{
stringBuilder.Append(line);
}
}
var json = stringBuilder.ToString(); // COMPLETE json response everytime!!!
You could try specifying the buffer size of the response content
var client = new HttpClient();
client.MaxResponseContentBufferSize = <your_buffer_size>;
Where the property MaxResponseContentBufferSize means:
Gets or sets the maximum number of bytes to buffer when reading the response content.

Rest Post call with Authentication Token

I'm trying to send a Post request to SharePoint Online (Claims Based Auth Site) from my client application (WPF application). In this case it should be an update to a ListItem to change the 'Title' to 'Test'.
I'm retrieving the CookieContainer via MsOnlineClaimsHelper Class
which successfully returns me an auth token.
But when i try to send the request the response is The remote server returned an error: (403) Forbidden.
WebRequest Code
try
{
var claimshelper = new MsOnlineClaimsHelper(baseUrl, _userName, _password);
var request = (HttpWebRequest)WebRequest.Create(baseUrl + "/" + url);
request.CookieContainer = claimshelper.CookieContainer;
request.Method = "POST";
request.Headers.Add("X-HTTP-Method", "MERGE");
request.Headers.Add("If-Match", "*");
request.Accept = "application/json;odata=verbose";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
}
var webResp = request.GetResponse() as HttpWebResponse;
var theData = new StreamReader(webResp.GetResponseStream(), true);
string payload = theData.ReadToEnd();
}
catch (Exception ex)
{
}
Rest Url:
/_api/lists/getbytitle('SampleList')/items(1)
Json Payload:
string json = "{ '__metadata': { 'type': 'SP.Data.SampleListListItem' }, 'Title': 'Test'}";
Error:
The remote server returned an error: (403) Forbidden.
This error occurs since SharePoint 2013 REST service requires the user to include a Request Digest value with each create, update and delete operation. This value is then used by SharePoint to identify non-genuine requests.
How to provide Request Digest value
In MsOnlineClaimsHelper class (MsOnlineClaimsHelper.cs file) add the following method to request Form Digest value:
/// <summary>
/// Request Form Digest value
/// </summary>
/// <returns></returns>
private string GetFormDigest()
{
var endpoint = "/_api/contextinfo";
var request = (HttpWebRequest) WebRequest.Create(_host.AbsoluteUri + endpoint);
request.CookieContainer = new CookieContainer();
request.Method = "POST";
//request.Accept = "application/json;odata=verbose";
request.ContentLength = 0;
using (var response = (HttpWebResponse)request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
var result = reader.ReadToEnd();
// parse the ContextInfo response
var resultXml = XDocument.Parse(result);
// get the form digest value
var e = from e in resultXml.Descendants()
where e.Name == XName.Get("FormDigestValue", "http://schemas.microsoft.com/ado/2007/08/dataservices")
select e;
_formDigest = e.First().Value;
}
}
return _formDigest;
}
and FormDigest property:
private string _formDigest;
public string FormDigest
{
get
{
if (_formDigest == null || DateTime.Now > _expires)
{
return GetFormDigest();
}
return _formDigest;
}
}
How to perform an update operation for a ListItem using SharePoint 2013 REST API
The following example demonstrates how to perform an update of a list item using the provided implementation for requesting a Form Digest
Key Points:
X-RequestDigest header is used to specify Form Digest value
Request Content Type have to be specified
Example:
var userName = "username#contoso.onmicrosoft.com";
var password = "password";
var payload = "{ '__metadata': { 'type': 'SP.Data.TasksListItem' }, 'Title': 'New Tasl'}"; //for a Task Item
try
{
var claimshelper = new MsOnlineClaimsHelper(baseUrl, _userName, _password);
var request = (HttpWebRequest)WebRequest.Create(baseUrl + "/" + endpointUrl);
request.CookieContainer = claimshelper.CookieContainer;
request.Headers.Add("X-RequestDigest", claimshelper.FormDigest);
request.Method = "POST";
request.Headers.Add("X-HTTP-Method", "MERGE");
request.Headers.Add("If-Match", "*");
request.Accept = "application/json;odata=verbose";
request.ContentType = "application/json;odata=verbose";
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(payload);
writer.Flush();
}
var response = request.GetResponse() as HttpWebResponse;
//...
}
catch (Exception ex)
{
//Error handling goes here..
}

Sending HTTP POST Request with XML to a web service and reading response data in C# for windows 8 phone

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();
}
}

Object reference not set to an instance of an object request.GetResponse()

public static string Method_Name(
string requestMethod,
string requestUrl,
string requestBody = null,
Dictionary<string, string> requestHeader = null,
string requestUserAgent = null,
Boolean isContentType = false)
{
string responseString = String.Empty;
try
{
Uri requestUri = new Uri(requestUrl);
WebRequest request = WebRequest.Create(requestUri);
request.Timeout = 60000;
if (requestHeader != null)
{
foreach (string key in requestHeader.Keys)
{
request.Headers.Add(key, requestHeader[key]);
}
}
request.Headers.Add("X-FD-TrustLevel", "trusted");
request.Headers.Add("X-FD-Version", "1.0");
request.Method = requestMethod;
// For MAS 1.0 POST Call
if (isContentType)
{
request.ContentType = #"application/json";
}
if (!String.IsNullOrEmpty(requestUserAgent))
{
((HttpWebRequest)request).UserAgent = requestUserAgent;
}
if (!String.IsNullOrEmpty(requestBody))
{
Stream stream = request.GetRequestStream();
string requestString = requestBody;
stream.Write(Encoding.Default.GetBytes(requestString), 0, requestString.Length);
stream.Close();
}
/* ERROR */ HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader responseStream = new StreamReader(response.GetResponseStream()))
{
responseString = responseStream.ReadToEnd();
}
}
catch (Exception ex)
{
AnswersExceptionCollection.GetInstance().AddException(ex);
}
return responseString;
}
}
I am getting the following message when code execution reaches HttpWebResponse response = (HttpWebResponse)request.GetResponse();:
Error occurred - Object reference not set to an instance of an object.
I am aware why this kind of error happens, but I am not able to find the root cause in this particular case. Any help will be much appreciated.
Problem must be in these two lines
Uri requestUri = new Uri(requestUrl);
WebRequest request = WebRequest.Create(requestUri);
Verify with breakpoint after executing these lines that whether request is null or not.
If it is null then your provided URL may not exists or may have some other problem.
Regards,
Pavan.G
It seems your initiation on the request
WebRequest request = WebRequest.Create(requestUri);
needs some details of the kind of request. If you're trying to get HttpWebResponse, you have to catch response from HttpWebRequest. here is a quote from MSDN Article.
NoteNote
The WebRequest class is an abstract class.The actual behavior of
WebRequest instances at run time is determined by the descendant class
returned by the WebRequest.Create method.For more information about
default values and exceptions, see the documentation for the
descendant classes, such as HttpWebRequest and FileWebRequest.
So that meant you'll get this clear if you create the request like that
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri)

Categories