public async static Task<RootObject> GetWeather(string username, string password)
{
var http = new HttpClient();
var response = await http.GetAsync(postURI);
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var datax = (RootObject)serializer.ReadObject(ms);
return datax;
}
I have the necessary models ready and I made the function call with some hard-coded data to test but its not working.
Related
I recently upgraded RestSharp to version 107.3.0. I had to modify my request some, but the Web API gets the request and returns, but it hangs there waiting for the response...
private async Task<bool> AuthenticateUser(string username, string password)
{
var encryption = new Encryption64();
var encrypt = encryption.Encrypt(password, _key);
var client = new RestClient(UserSettings.URL);
var uri = $"users/authenticate/{username}/";
var pass = new PasswordDTO
{
Password = encrypt
};
var request = new RestRequest(uri)
.AddJsonBody(pass);
//var json = JsonConvert.SerializeObject(pass);
//request.AddParameter("application/json; charset=utf-8", json, ParameterType.RequestBody);
var response = await client.PostAsync<bool>(request);
return response;
}
The line await client.PostAsync<bool>(request) never completes. No errors in the Debug window either. This worked before I upgraded. What am I doing wrong?
I am not sure if this is entirely correct... but I fiddled with it until I got it working.
private bool AuthenticateUser(string username, string password)
{
using (var client = new RestClient(UserSettings.URL))
{
var encryption = new Encryption64();
var encrypt = encryption.Encrypt(password, _key);
var uri = $"users/authenticate/{username}/";
var pass = new PasswordDTO
{
Password = encrypt
};
var request = new RestRequest(uri)
.AddJsonBody(pass);
var response = client.PostAsync<bool>(request).Result;
return response;
}
}
UPDATE
private async Task<bool> AuthenticateUser(string username, string password)
{
using (var client = new RestClient(UserSettings.URL))
{
var encryption = new Encryption64();
var encrypt = encryption.Encrypt(password, _key);
var uri = $"users/authenticate/{username}/";
var pass = new PasswordDTO
{
Password = encrypt
};
var request = new RestRequest(uri)
.AddJsonBody(pass);
var response = await client.PostAsync<bool>(request);
return response;
}
}
public async Task<bool> AuthenticateUserAsync([FromUri] string username, [FromBody] PasswordDTO pass)
{
Log.Logger.ForContext<UserController>().Information("{User} is Logging In", username);
using (var context = new DatabaseContext())
{
var user = await context.bma_users
.AsNoTracking()
.FirstOrDefaultAsync(p => p.username == username);
if (user is null)
return false;
return (user.password == pass.Password);
}
}
I still welcome any ideas for improvement.
I am running into a deadlock situation when trying to post to WebApi 2 from WebApi 1 using HttpClient PostAsync and using async and await.
Below is WebAPI 1:
public HttpResponseMessage Get([FromUri]int oid)
{
var orderdetails = _orderServices.GetOrderDetails(oid);
var xml = new XmlMediaTypeFormatter();
xml.UseXmlSerializer = true;
string orderdetailsser = Serialize(xml, orderdetails);
var result = PostXml(orderdetailsser);
return Request.CreateResponse(HttpStatusCode.OK);
}
public static async Task<HttpResponseMessage> PostXml(string str)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:58285/");
var content = new StringContent(str);
var response = await client.PostAsync("api/default/ReceiveXml", content).ConfigureAwait(false);
return response;
}
}
And WebApi2:
[System.Web.Http.HttpPost]
public HttpResponseMessage ReceiveXml(HttpRequestMessage request)
{
var xmlDoc = new XmlDocument();
xmlDoc.Load(request.Content.ReadAsStreamAsync().Result);
xmlDoc.Save(#"C:\xmlfiles\xml2.xml");
XmlSerializer deserializer = new XmlSerializer(typeof(OrderInfoModel));
TextReader reader = new StreamReader(#"C:\xmlfiles\xml2.xml");
object obj = deserializer.Deserialize(reader);
OrderInfoModel orderdetails = (OrderInfoModel)obj;
reader.Close();
var patient_id = _patientServices.ProcessPatient(orderdetails.Patient, orderdetails.OrderInfo);
var orderid = _orderServices.ProcessOrder(orderdetails.Patient, orderdetails.OrderInfo, patient_id);
if (orderdetails.OrderNotes != null && orderdetails.OrderNotes.Count() > 0)
{
var success = _orderServices.ProcessOrderNotes(orderid, orderdetails.OrderNotes);
}
var prvid = _orderServices.ProcessOrderProvider(orderid, orderdetails.ReferringProvider);
var shpngid = _orderServices.ProcessOrderShipping(orderid, orderdetails.ShippingInfo);
var payerid = _orderServices.ProcessOrderPayer(orderid, orderdetails.Insurances);
return Request.CreateResponse(HttpStatusCode.OK, orderid);
}
I am not getting any response back to WebAPI 1 from WebAPI 2. I have gone through several articles online about deadlock situation. However, I am unable to resolve the deadlock in my case. What am I doing wrong here? Am I using async and await properly?
To build off my comment above, modify your code so that you are not blocking on an async operation. Additionally _orderServices.GetOrderDetails(oid); sounds like a method that hits a database and as such should be await _orderServices.GetOrderDetailsAsync(oid); wherein you use the whatever async api is available for your database access.
[HttpGet()]
public async Task<HttpResponseMessage> Get([FromUri]int oid) {
var orderdetails = _orderServices.GetOrderDetails(oid);
var xml = new XmlMediaTypeFormatter();
xml.UseXmlSerializer = true;
string orderdetailsser = Serialize(xml, orderdetails);
var result = await PostXml(orderdetailsser);
return Request.CreateResponse(HttpStatusCode.OK);
}
public static async Task<HttpResponseMessage> PostXml(string str) {
using(var client = new HttpClient()) {
client.BaseAddress = new Uri("http://localhost:58285/");
var content = new StringContent(str);
var response = await client.PostAsync("api/default/ReceiveXml", content).ConfigureAwait(false);
return response;
}
}
[HttpPost()]
public async Task<HttpResponseMessage> ReceiveXml(HttpRequestMessage request) {
var xmlDoc = new XmlDocument();
xmlDoc.Load(await request.Content.ReadAsStreamAsync());
xmlDoc.Save(#"C:\xmlfiles\xml2.xml");
XmlSerializer deserializer = new XmlSerializer(typeof(OrderInfoModel));
TextReader reader = new StreamReader(#"C:\xmlfiles\xml2.xml");
object obj = deserializer.Deserialize(reader);
OrderInfoModel orderdetails = (OrderInfoModel)obj;
reader.Close();
var patient_id = _patientServices.ProcessPatient(orderdetails.Patient, orderdetails.OrderInfo);
var orderid = _orderServices.ProcessOrder(orderdetails.Patient, orderdetails.OrderInfo, patient_id);
if(orderdetails.OrderNotes != null && orderdetails.OrderNotes.Count() > 0) {
var success = _orderServices.ProcessOrderNotes(orderid, orderdetails.OrderNotes);
}
var prvid = _orderServices.ProcessOrderProvider(orderid, orderdetails.ReferringProvider);
var shpngid = _orderServices.ProcessOrderShipping(orderid, orderdetails.ShippingInfo);
var payerid = _orderServices.ProcessOrderPayer(orderid, orderdetails.Insurances);
return Request.CreateResponse(HttpStatusCode.OK, orderid);
}
Resources
Don't Block on Async Code
Avoid Async Void
I'm learning how to create WEB-API client
I've created some simple API:
[HttpGet]
public IHttpActionResult GetInfo()
{
return Ok("Its working!");
}
[HttpPost]
public IHttpActionResult PostInfo(ClientDataDto dto)
{
try
{
someMethod(dto.IdKlienta, dto.Haslo, dto.IdZgloszenia, dto.HardwareInfo, dto.SoftwareInfo);
return Ok("sent");
}
catch
{
return BadRequest();
}
}
For now I just trying to call GET method.
When I use Fiddler with addr
localhost:someport/api/Client2
its working
but when i try to do it by client, which code is below:
private static HttpClient client = new HttpClient();
static void Main(string[] args)
{
#region TESTONLY
var debug = new XMLData();
string HardwareInfoXML = debug.HardwareXML;
string SoftInfoXML = debug.SoftwareXML;
int id_zgloszenia = 20;
int idKlienta = 25;
//haslo = "202cb962ac59075b964b07152d234b70";
#endregion
var data = new ClientDataDto() { HardwareInfo = HardwareInfoXML, SoftwareInfo = SoftInfoXML, IdKlienta = idKlienta, IdZgloszenia = id_zgloszenia };
RunAsync(data);
}
private static async Task RunAsync(ClientDataDto data)
{
var stringContent = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.BaseAddress = new Uri(#"http://localhost:7774/api/client2/");
var url = new Uri(#"http://localhost:7774/api/client2/");
var res1 = await client.GetAsync(url);
var res = await client.PostAsync(url, stringContent);
res.EnsureSuccessStatusCode();
}
Application closing without any info at
var res1 = await client.GetAsync(url);
I have checked to see all exceptions in Debug exception Windows, but it is just closing after trying call GetAsync
PostASync doesn't work too.
What is wrong here?
i'm really sorry that i've posted simpe problem.
sulotion is to add .Wait() on RunAsync(data);
RunAsync(data).Wait();
I have an object.
I'am sending it this to my api project this way :
mymodel obj = new mymodel();
obj.prop = "this";
obj.prop2 = "prop2";
var content = JsonConvert.SerializeObject(obj);
var buffer = System.Text.Encoding.UTF8.GetBytes(content);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
string response = "";
using (HttpClient client = new HttpClient())
{
var rez = await client.PostAsync(uri + myenum.Insert, byteContent).ConfigureAwait(false);
response = rez.ToString();
}
In my api method i want to convert that string or http content again to model.
[ActionName("Insert")]
[HttpGet]
public bool Insert(string obj)
{
try
{
mymodel model = JsonConvert.DeserializeObject<mymodel>(obj);
How to handle object i'am sending with postasync in my api method ?
Any help ?
First you cannot use PostAsync on a HTTPGet method.
Second, I dont understand what you mean. If you are using json then you dont have to do anything. Just have a simple client method as such:
public async Task<TResult> PostAsync<TResult, TInput>(string uriString, TInput payload = null) where TInput : class
{
var uri = new Uri(uriString);
using (var client = GetHttpClient())
{
var jsonContent = JsonConvert.SerializeObject(payload, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
HttpResponseMessage response = await client.PostAsync(uri, new StringContent(jsonContent, Encoding.UTF8, "application/json"));
if (response.StatusCode != HttpStatusCode.OK)
{
//Log.Error(response.ReasonPhrase);
return default(TResult);
}
var json = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<TResult>(json);
}
}
And you can just add the same object to your API like
[ActionName("Insert")]
[HttpPost]
public bool Insert(YourObjectClass obj)
{
try
{
....code....
}
}
Before Twitter switched to OAuth2, I was using the following query:
string atomTweetSearchURL = string.Format("http://search.twitter.com/search.atom?q={0}", searchText);
This no longer works, so now I'm trying to switch to OAuth2. I manage to successfully retrieve a token, but once I've got this, I seem to be unable to actually perform the search. Here's the latest incarnation of what I've tried:
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}&access_token={1}&token_type={2}", srchStr, twitAuthResponse.access_token, twitAuthResponse.token_type);
WebRequest srchRequest = WebRequest.Create(searchUrl);
using (var response2 = await srchRequest.GetResponseAsync())
{
Stream stream = response2.GetResponseStream();
using (StreamReader sr = new StreamReader(stream))
{
string jsonResponse = await sr.ReadToEndAsync();
}
}
This gives me a 400 - bad request.
I've also tried building the request like this:
System.Net.Http.HttpClient srchRequest = new System.Net.Http.HttpClient();
string authHdr = string.Format(srchHeaderFormat, twitAuthResponse.token_type, twitAuthResponse.access_token);
srchRequest.DefaultRequestHeaders.Add("Authorization", authHdr);
There's a massive quantity of articles out there detailing how to do this, but none of them seem to work correctly with WinRT. Can anyone point me in the right direction?
EDIT
Here's my code to get the token:
var oAuthConsumerKey = key;
var oAuthConsumerSecret = secret;
var oAuthUri = new Uri("https://api.twitter.com/oauth2/token");
var authHeaderFormat = "Basic {0}";
var authHeader = string.Format(authHeaderFormat,
Convert.ToBase64String(Encoding.UTF8.GetBytes(Uri.EscapeDataString(oAuthConsumerKey)
+ ":" +
Uri.EscapeDataString((oAuthConsumerSecret)))
));
var req = new HttpClient();
req.DefaultRequestHeaders.Add("Authorization", authHeader);
HttpRequestMessage msg = new HttpRequestMessage(new HttpMethod("POST"), oAuthUri);
msg.Content = new HttpStringContent("grant_type=client_credentials");
msg.Content.Headers.ContentType = new Windows.Web.Http.Headers.HttpMediaTypeHeaderValue("application/x-www-form-urlencoded");
HttpResponseMessage response = await req.SendRequestAsync(msg);
TwitAuthenticateResponse twitAuthResponse;
using (response)
{
string objectText = await response.Content.ReadAsStringAsync();
twitAuthResponse = JSonSerialiserHelper.Deserialize<TwitAuthenticateResponse>(objectText);
}
With the 1.1 API you don't pass the access token as part of the url, you need to include it as the Authorization header as "Bearer access_token" so you were almost there!
EDIT
To do this in the Windows.Web.Http namespace the following works:
private static async Task SearchTweets(AuthenticationResponse twitAuthResponse)
{
string srchStr = "tweet";
var client = new HttpClient();
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}", srchStr);
var uri = new Uri(searchUrl);
client.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue("Bearer", twitAuthResponse.AccessToken);
var response2 = await client.GetAsync(uri);
string content = await response2.Content.ReadAsStringAsync();
}
Or with System.Net.Http use the following:
This code will run the search for srchStr using the access token you already acquired as you showed in the first example:
var client = new HttpClient();
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}", srchStr);
var uri = new Uri(searchUrl);
client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", twitAuthResponse.access_token));
HttpResponseMessage response = await client.GetAsync(uri);
Task<string> content = response.Content.ReadAsStringAsync();
EDIT
This is a strange one, I tested your code and you're right it does throw an exception when attempting to add the Auth header, however the code I had used for grabbing the Access Token is almost identical but uses the System.Net.Http methods rather than the Windows.Web.Http ones that you use and it works, so I'll provide my code here, maybe this is a bug in the framework, or someone else can provide some more insight! This also uses the JSON.NET library which can be found on NuGet.
private static async Task SearchTweets(AuthenticationResponse twitAuthResponse)
{
string srchStr = "tweet";
var client = new HttpClient();
var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}", srchStr);
var uri = new Uri(searchUrl);
client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", twitAuthResponse.AccessToken));
HttpResponseMessage response2 = await client.GetAsync(uri);
string content = await response2.Content.ReadAsStringAsync();
}
private async void GetAuthenticationToken()
{
var client = new HttpClient();
var uri = new Uri("https://api.twitter.com/oauth2/token");
var encodedConsumerKey = WebUtility.UrlEncode(TwitterConsumerKey);
var encodedConsumerSecret = WebUtility.UrlEncode(TwitterConsumerSecret);
var combinedKeys = String.Format("{0}:{1}", encodedConsumerKey, encodedConsumerSecret);
var utfBytes = System.Text.Encoding.UTF8.GetBytes(combinedKeys);
var encodedString = Convert.ToBase64String(utfBytes);
client.DefaultRequestHeaders.Add("Authorization", string.Format("Basic {0}", encodedString));
var data = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "client_credentials")
};
var postData = new FormUrlEncodedContent(data);
var response = await client.PostAsync(uri, postData);
AuthenticationResponse authenticationResponse;
using (response)
{
if (response.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception("Did not work!");
var content = await response.Content.ReadAsStringAsync();
authenticationResponse = JsonConvert.DeserializeObject<AuthenticationResponse>(content);
if (authenticationResponse.TokenType != "bearer")
throw new Exception("wrong result type");
}
await SearchTweets(authenticationResponse);
}
}
class AuthenticationResponse
{
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("access_token")]
public string AccessToken { get; set; }
}