WinRt C# HttpClient SendAsync does not return - c#

I am creating a Metro App that makes a HTTP Post request to a webserver to obtain JSON data. Initially I use the same code to logon to the web server and the HTTP Post request returns fine. It is only later that I run into an issue where the code hangs when I call the SendAsync() method.
I used wireshark to view the network traffic and I did see the server returning a response. So I am not sure why the call is not completing. Anyone have any ideas?
Here is the code I am using:
var httpHandler = new HttpClientHandler();
httpHandler.CookieContainer = __CookieJar;
var httpClient = new HttpClient(httpHandler);
UserAgentDetails userAgent = UserAgentDetails.GetInstance();
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(userAgent.UserAgentString);
foreach (string key in __colHeaders)
httpClient.DefaultRequestHeaders.Add(key, __colHeaders[key]);
var content = new StringContent(postData);
if (contentType != null && contentType.Length > 0)
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
var requestMsg = new HttpRequestMessage(HttpMethod.Post, new Uri(url));
requestMsg.Content = content;
requestMsg.Headers.TransferEncodingChunked = true;
var responseMsg = await httpClient.SendAsync(requestMsg);
// no return from method after logon

Related

Calling Get Request with Json Body using httpclient

I came with an issue this morning where the Api which I am calling is a Get Method but to get Get the Data from it I had to send the json body this is working good when I am testing it in the post man but I am not able to implement it in my project where I am calling this using HttpClient
here is the screenshot of post
It also have a bearer token which I pass in Authorization
Now when I am try to implement this at client side here is my code
var stringPayload = JsonConvert.SerializeObject(json);
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://myapiendpoint/serviceability/"),
Content = new StringContent(stringPayload, Encoding.UTF8, "application/json"),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
when I call this method using this code I get
System.Net.HttpStatusCode.MethodNotAllowed - Status code 405
I also tried changing this line
Method = HttpMethod.Get to Method = HttpMethod.Post
but still getting same error
I know this is bad implementation at API Side the request ideally should be POST but changing this is not in my hand and hence need to find the solution
almost search all over and trying all the variant of using GET Method finally the solution which worked for me in this case was this
var client = new HttpClient();
client.BaseAddress = new Uri("https://baseApi/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", token));
var query = new Dictionary<string, string>
{
["pickup_postcode"] = 400703,
["delivery_postcode"] = 421204,
["cod"] = "0",
["weight"] = 2,
};
var url = "methodurl";
var response = await client.GetAsync(QueryHelpers.AddQueryString(url, query));
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonConvert.DeserializeObject<MyModel>(responseBody);
Got QueryHelpers from Microsoft.AspNetCore.WebUtilities package

How to display a PDF file in ASP.NET web app

I have a web api and a web app both written in asp.net and want to send a PDF from the api to the web app for display in a new browser window, the api is working sending the file as a streamcontent but i cannot find a way of prompting the client browser to display this in a new window, i cant make the browser make the request to the api directly as i need to add an authentication header first.
Does anyone have any ideas?
As an alternative if this is not possible i could also have the file downloaded to the client machine but i also dont know how to do that.
api code:
public HttpResponseMessage Get()
{
var response = new HttpResponseMessage();
string auth;
try
{
auth = Request.Headers.Authorization.Parameter;
}catch { return new HttpResponseMessage(HttpStatusCode.Unauthorized); }
if (auth == "test" || auth == null)
{
FileStream stream = File.OpenRead(Path.Combine(Storage.FilesDirectory, "0d23b37f-3ade-4342-beea-c6ba2cbf83cb.file"));
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
return response;
}
else return new HttpResponseMessage(HttpStatusCode.Forbidden);
}
Current client code that gets the stream but i dont know how to display that in the browser:
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, API.DocumentUrl);
req.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", "test");
var res = await HttpClientSingleton.Client.SendAsync(req);

RestSharp ignoring system proxy (for example Fiddler) on .NET Core

I want check the http traffic with Fiddler, but no any http traffic captured, my testing codes:
private static void ByRestSharp()
{
var restClient = new RestClient("https://jsonplaceholder.typicode.com");
var request = new RestRequest("posts", Method.GET);
var response = restClient.Get<List<Post>>(request);
Console.WriteLine("{0} posts return by RestSharp.", response.Data.Count);
}
But after I changed to use HttpClient, Fiddler can capture the http traffic, sample codes:
private static void ByHttpClient()
{
var httpClient = new HttpClient();
using (var req = new HttpRequestMessage(HttpMethod.Get, "https://jsonplaceholder.typicode.com/posts"))
using (var resp = httpClient.SendAsync(req).Result)
{
var json = resp.Content.ReadAsStringAsync().Result;
var users = SimpleJson.SimpleJson.DeserializeObject<List<Post>>(json);
Console.WriteLine("{0} posts return by HttpClient.", users.Count);
}
}
Is this a issue of RestSharp or Fiddler?
RestSharp supported system proxy until we moved to .NET Standard. Then, we got issues with proxy on .NET Core and then using the system proxy was removed entirely. We have an issue opened on Github and you can check the progress there.
However, explicitly setting the proxy should work for full .NET Framework, check this issue.
Code from the issue, which is confirmed to be working:
var client = new RestClient("http://www.google.com");
client.Proxy = new WebProxy("127.0.0.1", 8888);
var req = new RestRequest("/", Method.GET);
var resp = client.Execute(req);
Update 2018-05-31: RestSharp 106.3 is using the default proxy on .NET Core also, automatically. Tested with Fiddler.
Update 2022-02-23: RestSharp 107 has the Proxy property moved to RestClientOptions:
var options = new RestClientOptions("http://www.google.com") {
Proxy = new WebProxy("127.0.0.1", 8888)
};
var client = new RestClient(options);
var req = new RestRequest("/");
var resp = await client.ExecuteAsync(req);

why RestSharp Request method Change from POST to GET?

I am using RestSharp to post some data to a url. I am monitoring this operation using fiddler. when I use Simple .net HttpClient with this code:
using (var client = new HttpClient())
{
var values = new Dictionary<string, string> {
{ "par1", "1395/11/29" },
{ "par2", "2" }};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://someurl.com/resource", content);
var responseString = await response.Content.ReadAsStringAsync();
}
every thing is good and this return true result. but when i try to use RestSharp with this code:
RestSharp.RestRequest request = new RestSharp.RestRequest("/resource");
request.AddParameter("par1", val, RestSharp.ParameterType.RequestBody);
request.AddParameter("par2", val, RestSharp.ParameterType.RequestBody);
request.AddHeader("Origin", "http://someurl.com");
request.Method = RestSharp.Method.POST;
RestSharp.RestClient client = new RestSharp.RestClient("http://someurl.com");
var response = client.Execute(request);
then fiddler show me the request sent by GET method instead of POST?
I check another time my fiddler and found this issue:
Content-Type: par1
why this is happening for me?
Change your ParameterType argument to GetOrPost and it will work
request.AddParameter("par1", val, RestSharp.ParameterType.GetOrPost);
request.AddParameter("par2", val, RestSharp.ParameterType.GetOrPost);
Initialize Request as POST with JSON.
var client = new RestClient(PreUri);
var request = new RestRequest(Uri, Method.POST) {RequestFormat = DataFormat.Json};
Add object in body
request.AddBody(obj);
Execute
var cancellationTokenSource = new CancellationTokenSource();
var response = await client.ExecuteTaskAsync(request, cancellationTokenSource.Token);
I was stupidly doing mistake to call "client.Get" instead of "client.Post". May be this post helps other.
var client = new RestClient("https://someservice.com");
var request = new RestRequest("/token/", Method.POST, DataFormat.Json).AddJsonBody(SomeObject);
var response = client.Get(request);
I was expecting this code to make POST request. Because i specified it as Method.POST.
But after a few hours, i saw my mistake. Yeas i was specifying the method. But just after i am calling client.Get(request); This changes the metod to GET.
So, the right way to use POST request is like follows:
var client = new RestClient("https://someservice.com");
var request = new RestRequest("/token/", DataFormat.Json).AddJsonBody(SomeObject);
var response = client.Post(request);

C# how to pass query string parameters in a post call

I have to call an external rest service from wpf application. I do not have any control on the service. When I make a request to the service using a rest client (e.g. Postman) it works fine i.e. success is returned. A post call is done to this URL:
http://mydomain.com:38080/workshop/rest/login?username=usr&password=pwd
You can see that I have to pass username and password in querystring.
But when I do the same from my application the service returns failed. Here is my code:
string EndPoint = "http://mydomain.com:38080/workshop/";
string parameters = "username=usr&password=pwd";
CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = cookies;
HttpClient client = new HttpClient(handler);
client.BaseAddress = new Uri(EndPoint);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.PostAsync("rest/login", new StringContent(parameters)).Result;
Task task = response.Content.ReadAsStreamAsync().ContinueWith(t =>
{
var stream = t.Result;
using (var reader = new StreamReader(stream))
{
responseValue = reader.ReadToEnd();
}
});
task.Wait();
It seems that the service is expecting parameters in querystring whereas my code is passing them in request header. So how do I pass the parameters in querystring in a post call?

Categories

Resources