I am making uwp(Universal Windows Platform) application and want to deserialize this xml: http://radioa24.info/ramowka.php to object, but I got instead for scpecial characters as ł, ó some strange letters and special ones like: \n and \r:
"Ä…"=>"ą"
"ć"=>"ć"
"Ä™"=>"ę"
For example instead of Poniedziałek i got PoniedziaÅ\u0082ek
My code:
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(uri).AsTask();
response.EnsureSuccessStatusCode();
var result = await httpResponse.Content.ReadAsStringAsync();
I was trying to make some Encoding convertions but nothing worked out.
How to solve it because later I want to got my object?
var reader = new XmlSerializer(typeof(Sources.Schedule));
using (var tr = new MemoryStream(Encoding.UTF8.GetBytes(resultString)))
{
Schedule = (Sources.Schedule)reader.Deserialize(res);
}
Please can you try the code below, reading data as bytes solves your issue.
using (HttpClient client = new HttpClient())
{
Uri url = new Uri("http://radioa24.info/ramowka.php");
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, url);
Task<HttpResponseMessage> responseAsync = client.SendRequestAsync(httpRequest).AsTask();
responseAsync.Wait();
responseAsync.Result.EnsureSuccessStatusCode();
Task<IBuffer> asyncBuffer = responseAsync.Result.Content.ReadAsBufferAsync().AsTask();
asyncBuffer.Wait();
byte[] resultByteArray = asyncBuffer.Result.ToArray();
string responseString = Encoding.UTF8.GetString(resultByteArray, 0, resultByteArray.Length);
responseAsync.Result.Dispose();
}
As Jon Skeet notes in his answer this should be fixed on the server. If you check the server sends back the following Content-Type header:
Content-Type: text/xml
It should tell you the encoding (Content-Type: text/xml; charset=utf-8), that's why it should be a server fix.
But if you are sure that this is UTF-8 (it is, because the response xml contains <?xml version="1.0" encoding="UTF-8"?>), you can do this:
var httpClient = new HttpClient();
var response = await httpClient.GetBufferAsync(uri);
var bytes = response.ToArray();
var properEncodedString = Encoding.UTF8.GetString(bytes);
Here is my example that works fine with Polish words.
Method to get xml from page:
public async Task<string> GetXMl(string uri)
{
string result = null;
using (HttpClient httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(uri);
result = await response.Content.ReadAsStringAsync();
}
return result;
}
Method to deserialize xml:
public void DeserializeXml(string xml)
{
var serializer = new XmlSerializer(typeof(ramowka));
var buffer = Encoding.UTF8.GetBytes(xml);
using (var stream = new MemoryStream(buffer))
{
var ramowka = (ramowka)serializer.Deserialize(stream);
}
}
Example how to use methods, for example in button click event:
private async void Button_Click(object sender, RoutedEventArgs e)
{
string xml = await GetXMl("http://radioa24.info/ramowka.php");
DeserializeXml(xml);
}
Also here you are converted by Visual Studio xml to C# classes
http://pastebin.com/aJ4B1aCF
Related
So I've looked around for an answer for this but nothing I've found even comes close to solving it.
I'm trying to set up a Post method on my Web API but no matter what I do it just gives me an internal server error.
I've tried adding [FromBody] (it's a simple type).
HttpClient client {get;set;}
public APICall()
{
client = new HttpClient
{
BaseAddress = new Uri("http://localhost:1472/api/")
};
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-protobuf"));
}
public void PostTimeTaken(long timeTaken)
{
var response = client.PostAsJsonAsync("Logging", timeTaken).Result;
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.ReasonPhrase);
}
}
and then my controller action looks like this:
public void Post([FromBody] long timeTaken)
{
_api.DataBuilder.NumberOfAPICalls += 1;
_api.DataBuilder.ResponseTimes.Add(timeTaken);
}
I get no error message that could actually explain what's going on, just "Internal server error"
------SOLVED-------
Just in case anyone stumbles across this looking for the same answer, the issue was I was sending the data to the server in an incorrect format, it needed to be ProtoBuf serialised first, code snippet for anyone it might help:
public void PostToAPI(int ThingToSend)
{
using (var stream = new MemoryStream())
{
// serialize to stream
Serializer.Serialize(stream, ThingToSend);
stream.Seek(0, SeekOrigin.Begin);
// send data via HTTP
StreamContent streamContent = new StreamContent(stream);
streamContent.Headers.Add("Content-Type", "application/x-protobuf");
var response = client.PostAsync("Logging", streamContent);
Console.WriteLine(response.Result.IsSuccessStatusCode);
}
}
using (var client = new HttpClient())
{
string url = "http://localhost:7936";
client.BaseAddress = new Uri(url);
var jsonString = JsonConvert.SerializeObject(contentValue);
var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
var result = await client.PostAsync("/Api/Logger/PostActionLog", content);
string resultContent = await result.Content.ReadAsStringAsync();
}
Have you tried to convert
long timeTaken to A model like;
public class TimeModel {
public long TimeTaken {get;set;}
}
public void Post([FromBody] TimeModel time){
// Do Stuff
}
Here the code of creating a simple server
baseUrl = "http://localhost:1472/"; // change based on your domain setting
using (WebApp.Start<StartUp>(url: baseUrl))
{
HttpClient client = new HttpClient();
var resp = client.GetAsync(baseUrl).Result;
}
Here some changes in your code
var requestData = new List<KeyValuePair<string, string>> // here
{
new KeyValuePair<string, string>( "Logging",timeTaken),
};
Console.WriteLine("request data : " + requestData);
FormUrlEncodedContent requestBody = newFormUrlEncodedContent(requestData);
var request = await client.PostAsync("here pass another server API", requestBody);
var response = await request.Content.ReadAsStringAsync();
Console.WriteLine("link response : " + response);
Pls add your controller
[HttpPost] // OWIN - Open Web Interface for .NET
public HttpResponseMessage Post([FromBody] long timeTaken)
{
_api.DataBuilder.NumberOfAPICalls += 1;
_api.DataBuilder.ResponseTimes.Add(timeTaken);
return Request.CreateResponse(HttpStatusCode.OK); //Using Post Method
}
I got a little question: I would like to stream an large array from my web API to my client. But I got a System.OutOfMemory Exception or an AggregateException.
My Api looks like this:
public List<MyLittlePony> Get()
{ return GetLittlePonys();}
And my Client looks like:
public string GetRequest(string URL)
{
using (var client = new System.Net.Http.HttpClient())
{
// HTTP POST
client.BaseAddress = new Uri(URL);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.GetAsync("").Result;
string res = "";
using (HttpContent content = response.Content)
{
// ... Read the string.
Task<string> result = content.ReadAsStringAsync();
return result.Result;
}
}
If I'm dealing with a small size of Objects, everything works fine.
But the large one does not work.
I don't want to work with creating files or things like this.
I solved it by using this (Web API):
public HttpResponseMessage Get()
{
var result = GetLittlePonys();
var response = Request.CreateResponse();
response.Content =
new PushStreamContent((stream, content, context) =>
{
var serializer = new JsonSerializer();
using (var writer = new StreamWriter(stream))
{
serializer.Serialize(writer, result);
stream.Flush();
}
});
return response;
}
But now I have the Problem that it takes over 1 minute to transfer about 60000 elements. And this is too long for my client. Can Someone help?
I am trying to upload an image using Zendesk API v2, I am posting the file to /api/v2/uploads.json using RestSharp, and the file appears in the ticket once I create the ticket and add the attachment, the issue is that if I upload an image it won't open on the ticket, it is broken, if its a .txt file it has extra data there, this is my method:
var client = new RestSharp.RestClient(model.RequestUri);
client.Authenticator = new HttpBasicAuthenticator(string.Format("{0}/token", model.Username), model.Password);
var request = new RestRequest("/api/v2/uploads.json", Method.POST);
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "text/plain");
request.AlwaysMultipartFormData = true;
request.Parameters.Clear();
request.RequestFormat = RestSharp.DataFormat.Json;
//request.AddBody(createUpload);
byte[] bytes = System.IO.File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/Media/uploads/test.txt"));
request.AddFileBytes("Attachment", bytes, "test.txt", contentType: "text/plain");
request.AddParameter("filename", "test.txt");
IRestResponse response = client.Execute(request);
var content = JObject.Parse(response.Content);
return content["upload"]["token"].ToString();
This is the resulting txt file that's attached to the ticket:
-------------------------------28947758029299
Content-Disposition: form-data; name="filename"
test.txt
-------------------------------28947758029299
Content-Disposition: form-data; name="Attachment"; filename="test.txt"
Content-Type: application/octet-stream
testing txt
-------------------------------28947758029299--
The original file just has:
testing txt
Any ideas of what the error could be?
Thanks.
I solved the issue using an external library called ZendeskApi that's recommended in the Zendesk documentation: https://github.com/justeat/ZendeskApiClient
By using this library I was able to upload the attachments successfully and it works with any kind of file as well. It is also very easy to use, my method looks like this now:
IZendeskClient client = new ZendeskClient(
new Uri(model.RequestUri),
new ZendeskDefaultConfiguration(model.Username,
model.Password)
);
UploadRequest request = new UploadRequest() {
Item = model.Attachment.ConvertToZendeskFile()
};
IResponse<Upload> response = client.Upload.Post(request);
return response.Item.Token;
This is the ConvertToZendeskFile method:
private static ZendeskFile ConvertToZendeskFile(this HttpPostedFileBase rawFile)
{
return new ZendeskFile()
{
FileName = rawFile.FileName,
ContentType = rawFile.ContentType,
InputStream = rawFile.InputStream
};
}
The last step was creating a class that implemented IHttpPostedFile from the API:
public class ZendeskFile : IHttpPostedFile
{
public string ContentType { get; set; }
public string FileName { get; set; }
public Stream InputStream { get; set; }
}
This solved the issue for me, I hope it can help anyone facing the same problem.
I've managed to upload images and PDFs to Zendesk using a code snippet similar to this:
var client = new RestClient(apiUrl);
client.Authenticator = new HttpBasicAuthenticator(username + "/token", token);
client.AddDefaultHeader("Accept", "application/json");
string name = "name";
byte[] data; //Read all bytes of file
string filename = "filename.jpg";
var request = new RestRequest("/uploads.json", Method.POST);
request.AddFile(name, data, filename, "application/binary");
request.AddQueryParameter("filename", filename);
var response = client.Execute(request);
Need to add header ContentType=application/binary and provide file name in the URI ?filename=myfile.dat:
HttpClient client = [...];
var content = new ByteArrayContent(fileByteArray);
content.Headers.ContentType = new MediaTypeHeaderValue("application/binary");
HttpResponseMessage response = await client.PostAsync(url, content);
string responseString = await response.Content.ReadAsStringAsync();
From Zendesk documentation:
curl "https://{subdomain}.zendesk.com/api/v2/uploads.json?filename=myfile.dat&token={optional_token}" \
-v -u {email_address}:{password} \
-H "Content-Type: application/binary" \
--data-binary #file.dat -X POST
I had the same problem, Restsharp was sending the file as multipart, the only solution that worked for me was to send the file as parameter with content "application/binary".
public string UploadFile(ZendeskFile file)
{
try
{
var request = new RestRequest(FileUploadsPath, Method.POST);
request.AddQueryParameter("filename", file.Name);
request.AddParameter("application/binary", file.Data, ParameterType.RequestBody);
var response = Execute<UploadZendeskFileResponse>(request);
var result = JsonConvert.DeserializeObject<UploadZendeskFileResponse>(response.Content);
return result.upload.token;
}
catch (Exception ex)
{
throw ex;
}
}
I hope this helps someone else.
In my case, I did something like this. Hope you won't waste 6 hours like me!
public async Task UploadImageToZendesk(IFormFile image)
{
byte[] fileByteArray;
var request = new HttpRequestMessage();
var client = new HttpClient();
await using (var fileStream = image.OpenReadStream())
await using (var memoryStream = new MemoryStream())
{
await fileStream.CopyToAsync(memoryStream);
fileByteArray = memoryStream.ToArray();
}
ByteArrayContent byteContent = new ByteArrayContent(fileByteArray);
request.Content = byteContent;
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse($"application/binary");
await client.SendAsync(request);
}
I am doing HTTP get request using HttpClient in C# console app . I am not getting expected response with one get request.
Get Request is like
http://example.com/xyz/SearchProduct?productNo=11210&1d6rstc9xc=5jyi27htzk
I am getting some vague response but when i do same get request with fiddler it is giving expected response.
How can I get expected response from httpClient.GetAsync(url)?
code is :-
var httpClient = new HttpClient();
var url = "http://example.com/xyz/SearchProduct?productNo=11210&1d6rstc9xc=5jyi27htzk";
HttpResponseMessage response1 = await httpClient.GetAsync(url);
if (response1.IsSuccessStatusCode)
{
HttpContent stream = response1.Content;
Task<string> data = stream.ReadAsStringAsync();
}
You should read as string that way:
string result = await stream.ReadAsStringAsync();
instead of that:
Task<string> data = stream.ReadAsStringAsync();
Here full code example and another example
This is a full method using async/await approach.
private static async Task<string> GetRequestContentAsString(string url)
{
var data = string.Empty;
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var stream = response.Content;
data = await stream.ReadAsStringAsync();
}
}
return data;
}
This method is called this way:
var content = await GetRequestContentAsString("http://www.bing.com");
I'm trying to learn about Async programming using VS2012 and its Async Await keyword. That is why i wrote this piece of code:
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
string get = await GetResultsAsync("http://saskir.medinet.se");
resultsTextBox.Text = get;
}
private async Task<string> GetResultsAsync(string uri)
{
HttpClient client = new HttpClient();
return await client.GetStringAsync(uri);
}
The problem is that when i try to debug the application, it gives me an error with this message:
The character set provided in ContentType is invalid. Cannot read content as string using an invalid character set.
I guess this is because the website have some Swedish char, but i can't find how to change the encoding of the response. Anyone can guide me plz?
You may have to check the encoding options and get the correct one. Otherwise, this code should get you going with the response.
private async Task<string> GetResultsAsync(string uri)
{
var client = new HttpClient();
var response = await client.GetByteArrayAsync(uri);
var responseString = Encoding.Unicode.GetString(response, 0, response.Length - 1);
return responseString;
}
In case you want a more generic method, following works in my UWP case in case someone has one with Unicode, would be great add the if:
var response = await httpclient.GetAsync(urisource);
if (checkencoding)
{
var contenttype = response.Content.Headers.First(h => h.Key.Equals("Content-Type"));
var rawencoding = contenttype.Value.First();
if (rawencoding.Contains("utf8") || rawencoding.Contains("UTF-8"))
{
var bytes = await response.Content.ReadAsByteArrayAsync();
return Encoding.UTF8.GetString(bytes);
}
}
WinRT 8.1 C#
using Windows.Storage.Streams;
using System.Text;
using Windows.Web.Http;
// in some async function
Uri uri = new Uri("http://something" + query);
HttpClient httpClient = new HttpClient();
IBuffer buffer = await httpClient.GetBufferAsync(uri);
string response = Encoding.UTF8.GetString(buffer.ToArray(), 0, (int)(buffer.Length- 1));
// parse here
httpClient.Dispose();