I'm calling an existing get method from a WebApi Controller which has this code (I cannot modify it)
[HttpGet]
public HttpResponseMessage Get()
{
XmlDataDocument xmldoc = new XmlDataDocument();
FileStream fs = new FileStream("d:\\document.xml", FileMode.Open, FileAccess.Read);
xmldoc.Load(fs);
string str = xmldoc.DocumentElement.InnerXml;
return new HttpResponseMessage() { Content = new StringContent(str, Encoding.UTF8, "application/xml") };
}
I've been trying to read this information like this
HttpClient client = new HttpClient();
HttpResponseMessage response = client.GetAsync("http://localhost/api/info");
HttpContent content = rm.Content;
I get a StreamContent but what I like to do now is to read this content and try to deserialize it into a Xml Document in order to read the nodes.
How can I get this information from the Stream Content of the HttpContent?
string response;
using(var http = new HttpClient())
{
response = await http.GetStringAsync("http://localhost/api/info");
}
var xml = new XmlDataDocument();
xml.LoadXml(response);
You can use GetStringAsync to get a string instead of an HttpContent object. You also missed the await in your GetAsync.
Note: code has not been tested
Related
Title says it all. I need to send an image through the body of a PUT request. This is the code I currently have.
static class Request
{
private readonly static HttpClient client = new HttpClient();
public static async Task<UploadRequest> Upload(string uri, string path)
{
FileStream fileStream = File.Open(path, FileMode.Open, FileAccess.Read);
StreamContent streamContent = new StreamContent(fileStream);
MultipartContent content = new MultipartContent();
content.Add(streamContent);
Debug.WriteLine("Making a PUT request");
var response = await client.PutAsync(uri, content);
var result = await response.Content.ReadAsStringAsync();
var deserializedResult = JsonConvert.DeserializeObject<UploadRequest>(result);
fileStream.Close();
Debug.WriteLine("Request made, returning result");
return deserializedResult;
}
}
Instead of using MultipartContent I instead passed in streamContent directly into client.PutAsync like so.
FileStream fileStream = File.Open(path, FileMode.Open, FileAccess.Read);
StreamContent streamContent = new StreamContent(fileStream);
Debug.WriteLine("Making a PUT request");
var response = await client.PutAsync(uri, streamContent);
However they both produce the same error on my api. Which is "message": "You did not upload an image.". I've checked the actual content of what I've passed in, in both cases when I passed in MultipartContent or streamContent into PutAsync.
The respective output (in order of which I've mentioned them) is System.Net.Http.MultipartContent and System.Net.Http.StreamContent so what exactly am I passing into the body?
Note
I previously asked the wrong question. This is the appropriate one.
I am putting together a test application using WebApi2 and HttpClient in a win forms app.
I have come accross an issue where my HttpClient request to a WebApi2 controller which returns an HttpResponseMessage doesnt return the ByteArrayContent.
WebApiController Code
[HttpGet]
public HttpResponseMessage DownloadFilePart(string fileName)
{
var path = Server.MapPath("~/App_Data/uploads/" + fileName);
var fileArray = System.IO.File.ReadAllBytes(path);
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(fileArray)
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue(System.Web.MimeMapping.GetMimeMapping(fileName));
response.Content.Headers.ContentLength = fileArray.Length;
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
return response;
}
WinForms Code using HttpClient
static async void GetFilePart(string hostrUri)
{
var httpClient = new HttpClient
{
BaseAddress = new Uri(hostrUri)
};
var request = new HttpRequestMessage(HttpMethod.Get, "/Home/DownloadFilePart/?fileName=Test.txt");
var responseMessage = httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
var memoryStream = new MemoryStream();
var stream = await responseMessage.Result.Content.ReadAsByteArrayAsync();
var fileToWriteTo = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\Temp\\Test.txt";
using (var fileStream = new FileStream(fileToWriteTo, FileMode.Create, FileAccess.Write, FileShare.None))
{
//copy the content from response to filestream
fileStream.Write(stream, 0, stream.Length);
}
}
When the request return from the WebApi and I write the bytes to file all that is written into the file is the actual headers from the WebApi response. Has anyone any ideas what the issue could be here?
Thanks
Your problem is here
httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
HttpCompletionOption.ResponseHeadersRead is summarized as
The operation should complete as soon as a response is available and headers are read. The content is not read yet.
This would explain why you only get the headers in your response.
Either remove it completely or change it to HttpCompletionOption.ResponseContentRead
static async void GetFilePart(string hostrUri)
{
var httpClient = new HttpClient
{
BaseAddress = new Uri(hostrUri)
};
var request = new HttpRequestMessage(HttpMethod.Get, "/Home/DownloadFilePart/?fileName=Test.txt");
var responseMessage = await httpClient.SendAsync(request);
var byteArray = await responseMessage.Content.ReadAsByteArrayAsync();
var fileToWriteTo = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\Temp\\Test.txt";
using (var fileStream = new FileStream(fileToWriteTo, FileMode.Create, FileAccess.Write, FileShare.None))
{
//copy the content from response to filestream
fileStream.Write(byteArray, 0, byteArray.Length);
}
}
I've got a problem with the XDocument class. I am loading information of online XML API, for my first WP8.1 App, like this:
try
{
var xmlDoc = XDocument.Load(_url);
return xmlDoc;
}
catch (XmlException)
{
HttpClient http = new HttpClient();
HttpResponseMessage response = await http.GetAsync(new Uri(_url));
var webresponse = await response.Content.ReadAsStringAsync();
var content = XmlCharacterWhitelist(webresponse);
var xmlDoc = XDocument.Parse(content);
return xmlDoc;
}
But both ways are returning the wrong encoding. For example German umlauts are shown the wrong way. Every XML file I load has
xml version="1.0" encoding="utf-8"
in the top line. Any ideas?
Rather than read the data into a byte array and decoding it yourself, just read it as a stream and let XDocument.Load detect the encoding from the data:
using (HttpClient http = new HttpClient())
{
using (var response = await http.GetAsync(new Uri(_url)))
{
using (var stream = await response.Content.ReadAsStreamAsync())
{
return XDocument.Load(stream);
}
}
}
I fixed it by doing this:
HttpClient http = new HttpClient();
var response = await http.GetAsync(new Uri(_url));
var buffer = await response.Content.ReadAsBufferAsync();
byte[] byteArray = buffer.ToArray();
string content = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
var xmlDoc = XDocument.Parse(content);
return xmlDoc;
Using an XmlReader should resolve issue
string content = "your xml here";
StringReader sReader = new StringReader(content);
XmlTextReader xReader = new XmlTextReader(sReader);
XDocument xmlDoc = (XDocument)XDocument.ReadFrom(xReader);
I am trying to consume an API in C#, this is the code for the request. It should be a simple JSON API, however I'm getting some irregularities here.
public static HttpResponseMessage sendRequest(List<Header> headers, string endpoint, string api_key, string api_secret)
{
using (var client = new HttpClient())
{
List<Header> headerlist = new List<Header>{};
if(headers != null)
headerlist = headers;
List<Header> signed = Helpers.sign(endpoint, api_secret);
foreach (Header header in signed)
{
headerlist.Add(header);
}
client.BaseAddress = new Uri("https://api.coinkite.com");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("X-CK-Key", api_key);
foreach (Header header in headerlist)
{
client.DefaultRequestHeaders.Add(header.Name, header.Data);
}
HttpResponseMessage response = client.GetAsync(endpoint).Result;
return response;
}
}
Which I am calling via
HttpResponseMessage result = Requests.sendRequest(null, "/v1/my/self", api_key, api_secret);
return result.Content.ToString();
However, when I write that to console it looks like:
System.Net.Http.SteamContent
Any clue as to what the issue is? I am not too familiar with the stream content type.
HttpContent does not implement ToString method. So you need to use result.Content.CopyToAsync(Stream) to copy the result content to a Stream.
Then you can use StreamReader to read that Stream.
Or you can use
string resultString = result.Content.ReadAsStringAsync().Result;
to read the result as string directly.This method no need to use StreamReader so I suggest this way.
Call GetResponse() on the HttpResponseMessage
Stream stream = result.GetResponseStream();
StreamReader readStream = new StreamReader(stream, Encoding.UTF8);
return readStream.ReadToEnd();
If you are only interested in the contents, you can get the string directly by changing
HttpResponseMessage response = client.GetAsync(endpoint).Result;
to
string response = client.GetStringAsync(endpoint).Result;
https://msdn.microsoft.com/en-us/library/hh551746(v=vs.118).aspx
I am developing this application where I need to send an XML file to a webservice and read it from the webservice, and applying the business logic from the webservice, it will send an XML as response.
The thing is that I do know how to read the response the webservice sends, but I don't know how to retrieve the XML that the request sends to the webservice, the variable always comes null. If someone could help me out, I'd be really glad.
Request Method:
(...)
using (var client = new HttpClient())
{
var XMLRequest = Util.BuildXML.CreateRequestXML();
string url = string.Format(WEB_API_HOST + "/Application/MyMethod/");
HttpRequestMessage httpRequest = new HttpRequestMessage()
{
RequestUri = new Uri(url, UriKind.Absolute),
Method = HttpMethod.Post,
Content = new StringContent(XMLRequest.ToString(), Encoding.UTF8, "text/xml")
};
var task = client.SendAsync(httpRequest).ContinueWith((taskwithmsg) =>
{
var response = taskwithmsg.Result;
if (response.IsSuccessStatusCode)
{
var xmlResponse = response.Content.ReadAsStringAsync().Result;
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlResponse);
var test = doc.SelectSingleNode("RESPONSE/...").InnerText;
}
else
{
var contentTask = response.Content.ReadAsStringAsync().Result;
throw new Exception(contentTask);
}
});
task.Wait();
}
(...)
And the Webservice ( that is supposed to receive the XML and read it)
[AcceptVerbs("GET", "POST")]
public HttpResponseMessage MyMethod(XmlDocument doc)
{
// Any doc.SelectSingleNode() wouldn't work, the doc variable is null.
var response = new StringBuilder();
response.Append("<?xml version=\"1.0\" standalone=\"yes\"?>");
response.Append("<RESPONSE>");
(...)
response.Append("</RESPONSE>");
var xmlResponse = new HttpResponseMessage()
{
Content = new StringContent(response.ToString(), Encoding.UTF8, "text/xml")
};
return xmlResponse;
}
So how do I get to read the xml in the "MyMethod" method?
Thanks a bunch!