When I execute the query in Firefox/IE I get the full response; but when I execute the same request with HttpClient I get only a part. I don't understand why.
Apparently the data are chunked that's why I specify the ResponseContentRead.
var requestUri = "https://api.guildwars2.com/v2/continents/1/floors/1";
HttpClient httpClient = new HttpClient();
var request = new HttpRequestMessage();
request.Method = HttpMethod.Get;
request.RequestUri = requestUri;
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead);
var result = await response.Content.ReadAsStringAsync();
Why Firefox/IE returns the right response and HttpClient an incomplete one ?
Result from HttpClient:
Result from Firefox/IE:
The code is inside a C# UWP app.
I have successfully ran your code and gotten the entire json string. However, I had to make a minor modification in order to get it working:
var requestUri = new Uri("https://api.guildwars2.com/v2/continents/1/floors/1");
HttpClient httpClient = new HttpClient();
var request = new HttpRequestMessage();
request.Method = HttpMethod.Get;
request.RequestUri = requestUri;
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead);
var result = await response.Content.ReadAsStringAsync();
Note the requestUri being initialized as an Uri instance instead of a string instance.
Also, the code has been tested in a console application.
EDIT: Here is a paste of what I got from the call. I've beautified the code to make it more readable. Perhaps it helps you validate if the content is as expected: Json result
Related
Trying to simply post a string to a web api to make sure it works and the json string doesn't seem to be there even though I can see it in the debugger.. Is there something obvious I am missing ?
RootObject ro = new RootObject();
ro.JobID = 9999;
var dataAsString = JsonConvert.SerializeObject(ro); //there is a json string here
var content = new StringContent(dataAsString);
var client = _clientFactory.CreateClient();
client.BaseAddress = new System.Uri("http://localhost:55816");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
var response = await client.PostAsJsonAsync("/api/Jobs/", content);
{"Files":null,"JobID":9999,"ReadyForPublish":false,"ScheduledJobID":null}
With an HttpClient you can directly use the result of JsonConvert.SerializeObject(ro); as the second argument to the PostAsJsonAsync. No need to use the StringContent.
I am trying the run the console application as a window service in dot-net core and able to create ,start ,stop and delete the service.
I am using PostAsync() method in application but the issue is that this method is working perfectly in console application but in window service most of the times PostAsync() never returned any response.
Any help would be highly appreciated. Thanks!
string abc=\"firstparameter\":\"English\",\"secondParameter\":\"Hindi\",\"Marks\":\"Result \"}";
var response = await client.PostAsync("url", new StringContent(ab, Encoding.UTF8, "application/json")).ConfigureAwait(false))
and By this way
var response = client.PostAsync("url", content).Result;
var objResult = response.Content.ReadAsStringAsync().Result;
I know this is a late response but just in case this could help someone here is my answer.
StringContent is not a good option when doing Post. You may want to use FormUrlEncodedContent:
var data = new Dictionary<string, string>
{
{ "firstparameter", "firstparametervalue" },
{ "secondparameter", "secondparametervalue" }
};
var content = new FormUrlEncodedContent(data);
var response = await client.PostAsync(apiUri, content);
Here is an example of how you can use it.
In this example I have used HttpClientFactory to create a HttpClient.
var userApi = httpClientFactory.CreateClient("UserApi");
var request = new HttpRequestMessage(HttpMethod.Post, "systemuser/login");
request.Content = new StringContent(JsonConvert.SerializeObject(loginRequest), Encoding.UTF8, "application/json");
var response = await userApi.SendAsync(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var body = await response.Content.ReadAsAsync<LoginResponse>();
return Ok(body);
}
return StatusCode((int)response.StatusCode);
Hope this helps
I am attempting to POST some JSON data to an API to add accounts.
The instructions specify the ids parameter can be: a string (comma-separated), or array of integers
I realize I could put comma delimited ids into the query string however I would like to POST this data as JSON as I may have a large number of these.
Here is what I have tried:
public static HttpClient GetHttpClient()
{
var property = Properties.Settings.Default;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(property.apiUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("X-OrgSync-API-Key", property.apiKey);
return client;
}
HttpClient client = Api.GetHttpClient();
string json = "{\"ids\":[10545801,10731939]}";
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{client.BaseAddress}/classifications/{classification.id}/accounts/add", httpContent);
It runs "successfully" but nothing actually gets set on the API server side.
Any ideas as to what I might be doing wrong here?
Additionally, any kind of tools/techniques etc., particularly in Visual Studio that would give me better visibility of the request/response traffic?
I know that this is possible as it correctly adds the account ids when I use a tool like Postman:
Regarding the Tools/Techniques, you can use Fiddler to capture the request and response on the fly to check if the Raw request is correct.
If you haven't used it before, have a look here for instructions on how to capture the requests and responses.
I was able to get the json string method working by changing the StringContent encoding type from Encoding.UTF8 to null OR Encoding.Default.
string json = "{\"ids\":[10545801,10731939]}";
var httpContent = new StringContent(json, Encoding.Default, "application/json");
var response = await client.PostAsync($"{client.BaseAddress}/classifications/{classification.id}/accounts/add", httpContent);
I also figured out a way to use an object containing an int array of ids with the Encoding.UTF8;
HttpClient client = Api.GetHttpClient();
var postData = new PostData {ids = new[] {10545801,10731939}};
var json = JsonConvert.SerializeObject(postData);
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{client.BaseAddress}/classifications/{classification.id}/accounts/add", httpContent);
If you don't want to go to the trouble of creating a class just to store post data you can use an anonymous type:
var postData = new { ids = new[] {10545801,10731939}};
var json = JsonConvert.SerializeObject(postData);
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{client.BaseAddress}/classifications/{classification.id}/accounts/add", httpContent);
Try below code it will work
using (var client= new HttpClient()) {
string json = "{\"ids\":[10545801,10731939]}";
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{client.BaseAddress}/classifications/{classification.id}/accounts/add", httpContent);
// If the response contains content we want to read it!
if (response .Content != null) {
var responseContent = await response.Content.ReadAsStringAsync();
//you will get your response in responseContent
}
I need to add http headers to the HttpClient before I send a request to a web service. How do I do that for an individual request (as opposed to on the HttpClient to all future requests)? I'm not sure if this is even possible.
var client = new HttpClient();
var task =
client.GetAsync("http://www.someURI.com")
.ContinueWith((taskwithmsg) =>
{
var response = taskwithmsg.Result;
var jsonTask = response.Content.ReadAsAsync<JsonObject>();
jsonTask.Wait();
var jsonObject = jsonTask.Result;
});
task.Wait();
Create a HttpRequestMessage, set the Method to GET, set your headers and then use SendAsync instead of GetAsync.
var client = new HttpClient();
var request = new HttpRequestMessage() {
RequestUri = new Uri("http://www.someURI.com"),
Method = HttpMethod.Get,
};
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
var task = client.SendAsync(request)
.ContinueWith((taskwithmsg) =>
{
var response = taskwithmsg.Result;
var jsonTask = response.Content.ReadAsAsync<JsonObject>();
jsonTask.Wait();
var jsonObject = jsonTask.Result;
});
task.Wait();
When it can be the same header for all requests or you dispose the client after each request you can use the DefaultRequestHeaders.Add option:
client.DefaultRequestHeaders.Add("apikey","xxxxxxxxx");
To set custom headers ON A REQUEST, build a request with the custom header before passing it to httpclient to send to http server.
eg:
HttpClient client = HttpClients.custom().build();
HttpUriRequest request = RequestBuilder.get()
.setUri(someURL)
.setHeader(HttpHeaders.CONTENT_TYPE, "application/json")
.build();
client.execute(request);
Default header is SET ON HTTPCLIENT to send on every request to the server.
Trying to send a rather long string to a REST web api (youtrack). I get the following exception:
Invalid URI: The Uri string is too long.
My code:
var encodedMessage = HttpUtility.UrlEncode(message);
var requestUri = string.Format("{0}{1}issue/{2}/execute?comment={3}", url, YoutrackRestUrl, issue.Id, encodedMessage);
var response = await httpClient.PostAsync(requestUri, null).ConfigureAwait(false);
So I took my chances with a FormUrlEncodedContent
var requestUri = string.Format("{0}{1}issue/{2}/execute", url, YoutrackRestUrl, issue.Id);
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("comment", message));
var content = new FormUrlEncodedContent(postData);
var response = await httpClient.PostAsync(requestUri, content).ConfigureAwait(false);
Which results in the exact same issue.
The string (comment) I am sending, is the changed file set of a commit into SVN. Which can be really long, so I don't really have a way to get around that. Is there a way to post content without the string length restriction?
Read the following topics, but didn't find an answer there:
.NET HttpClient. How to POST string value?
How do I set up HttpContent for my HttpClient PostAsync second parameter?
https://psycodedeveloper.wordpress.com/2014/06/30/how-to-call-httpclient-postasync-with-a-query-string/
http://forums.asp.net/t/2057125.aspx?Invalid+URI+The+Uri+string+is+too+long+HttpClient
Well the short answer to it - just put it into the Body, instead of trying to push all the data via the URL
But as the work on the ticket showed - the answer was here How to set large string inside HttpContent when using HttpClient?
The actual problem beeing in the FormUrlEncodedContent
Try this..Will be helpful for uwp..
Uri uri = new Uri("your uri string");
Windows.Web.Http.HttpClient client = new Windows.Web.Http.HttpClient();
var value1 = new System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string,string>>
{
// your key value pairs
};
var response = await client.PostAsync(uri,new HttpFormUrlEncodedContent(value1));
var result = await response.Content.ReadAsStringAsync();