Compiler Error Consuming Web API Call - c#

I need to implement a webapi call into a legacy ASP.Net Web Forms application.
I know not all of the usings are need for this method but they are for other methods on the page i included on the off chance that one of them is causing the problem.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
private string GetToken(string Username, string IpAddress)
{
string result = string.Empty;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(SSOApiUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("api/yourcustomobjects").Result;
if (response.IsSuccessStatusCode)
{
***var data = await response.Content.ReadAsStringAsync();***
var token = JsonConvert.DeserializeObject<GetSSOTokenResponse>(data);
result = token.Token;
}
return result;
}
When I try to compile my application I get the following error at the emphisized line:
Error 19 The 'await' operator can only be used within an async method.
Consider marking this method with the 'async' modifier and changing
its return type to 'Task< string>'.
I am trying to implement a solution similar to the one found in this question but it is failing. I need to call the WebAPI Method, and return part of the result as a string... not a Task< String>

The error is straightforward. You must have an async method to use the await keyword. Your return value will automatically be wrapped in a Task as a result by the compiler. Note that the .Result can be changed to an await as well. Here's the Microsoft documentation on the async/await keywords
private async Task<string> GetToken(string Username, string IpAddress)
{
string result = string.Empty;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(SSOApiUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("api/yourcustomobjects");
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
var token = JsonConvert.DeserializeObject<GetSSOTokenResponse>(data);
result = token.Token;
}
return result;
}

Related

error while testing the Echo Chat Bot on Azure

I'm following
https://towardsdatascience.com/creating-a-serverless-python-chatbot-api-in-microsoft-azure-from-scratch-in-9-easy-steps-2f1913fc9581
in creating a python chatbot, and my source code is as below, however when I try to run it, I'm getting an error. According to repositories that error is the adapter's on_error handler receives any exceptions thrown by bot's turn logic. If there is an exception thrown, the handler deletes the conversation state for the current conversation to prevent the bot from getting stuck in an error-loop caused by being in a bad state. any expert can help with this?
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;
using System.Net;
using System;
using System.Net.Http;
using System.Text; // for class Encoding
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace Microsoft.BotBuilderSamples.Bots
{
public class EchoBot : ActivityHandler
{
public class FlaskRequestModel
{
[JsonProperty("text")]
public string Text {get; set;}
}
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var replyText = $"{turnContext.Activity.Text}";
//if (!replyText.ToLower().Contains("Hey Bot")){ # Optional bit of code that only sends the sends the message to the back end if it contains a particular keyword
// return;
//}
var replyTextModel = new FlaskRequestModel()
{
Text = replyText
};
var jsonObject = JsonConvert.SerializeObject(replyTextModel);
var request = new HttpRequestMessage()
{
Content = new StringContent(jsonObject, Encoding.UTF8, "application/json"),
Method = HttpMethod.Post,
RequestUri = new Uri("yudao.azurewebsites.net"), // <- Replace the URL with the the URL for your function app
};
var httpClient = new HttpClient();
// httpClient.DefaultRequestHeaders.Add("API-Key","your API-key"); <- required if your HTTP trigger authorization was set to something other than Anonymous
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead);
if (response.IsSuccessStatusCode)
{
var responseString = await response.Content.ReadAsStringAsync();
await turnContext.SendActivityAsync(MessageFactory.Text(responseString, responseString), cancellationToken);
}
else
{
await turnContext.SendActivityAsync(MessageFactory.Text("failure", "failure"), cancellationToken);
var responseString = await response.Content.ReadAsStringAsync();
await turnContext.SendActivityAsync(MessageFactory.Text(responseString, responseString), cancellationToken);
}
}
}
}
try this using regex:
A2 = "12 15|||Pform|||their|||REQUIRED|||-NONE-|||0"
intval=[val for val in A2.split('|||') if bool(re.search(pattern='\d+', string=val))]
Output:
['12 15', '0']

Make my own API capable of requesting from another API

I have an existing and functioning API, which now have to be able to get data from another external API. How do i do that best?
I have tried with using HTTPClient, but i can't seem to get it to work. The error i get:
"No MediaTypeFormatter is available to read an object of type 'IList`1' from content with media type 'text/html'." -> I get this error on line 37. Can you spot it and/or tell me how I can do this differently, taking into account that all i want is the data (From the external API) and not to display it using a view, as this is an API?
Code below. I have also created a Pastebin: https://pastebin.com/MuKjEVys
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net;
namespace API.Controllers
{
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class ExternalApiController : Controller
{
private string ExternalApiLink = "https://blablabla.com/api";
private string ExternalApiLinkGet = "/module/1/";
[HttpGet("getdata")]
public ActionResult<ExternalApi> GetDataFromExternal()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ExternalApiLink);
var requestApi = client.GetAsync(ExternalApiLinkGet);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "XXXX");
requestApi.Wait();
var resultFromApi = requestApi.Result;
if (resultFromApi.IsSuccessStatusCode)
{
var readResponse = resultFromApi.Content.ReadAsAsync<IList<ExternalApi>>();
readResponse.Wait();
var data = readResponse.Result;
return Json(data);
}else
{
return NotFound();
}
}
}
}
}
Your response content seems to be json, while the content-type is text/html. If that is the case, the first thing to do would be to call the party that is exposing the service and have them fix it. In the meantime you could just read the content of the response as a string, and deserialize that string:
// Note that I made this method async.
public async Task<IActionResult> GetDataFromExternal()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ExternalApiLink);
// note that I moved this line above the GetAsync method.
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "XXXX");
// note that I'm disposing the response
using (var response = await client.GetAsync(ExternalApiLinkGet))
{
if (response.IsSuccessStatusCode)
{
// Since the response content is json, but the content-type
// is text/html, simply read the content as a string.
string content = await response.ReadAsStringAsync();
// You can return the actual received content like below,
// or you may deserialize the content before returning to make
// sure it is correct, using JsonConvert.DeserializeObject<List<ExternalApi>>()
// var data = JsonConvert.DeserializeObject<List<ExternalApi>>(content);
// return Json(data);
return Content(content, "application/json");
}
else
{
return NotFound();
}
}
}
}

'HttpWebRequest' does not contain a definition for 'GetResponseAsync'

I am new in xamarin and visual studio,I have followed this tuto from microsoft:
enter link description here
to create a cross platform application,but I get this error:
'HttpWebRequest' does not contain a definition for 'GetResponseAsync' and no extension method 'GetResponseAsync' accepting a first argument of type 'HttpWebRequest' was found (a using directive or an assembly reference is it missing * ?)
and this is my code in which I get this error:DataService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using Newtonsoft.Json;
namespace shared
{
//This code shows one way to process JSON data from a service
public class DataService
{
public static async Task<dynamic> getDataFromService(string queryString)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(queryString);
var response = await request.GetResponseAsync().ConfigureAwait(false);
var stream = response.GetResponseStream();
var streamReader = new StreamReader(stream);
string responseText = streamReader.ReadToEnd();
dynamic data = JsonConvert.DeserializeObject(responseText);
return data;
}
}
}
Please how can I solve it, I checked the HttpWebRequest documentation but I didn't get well the problem
thanks for help
Not sure about HttpWebRequest - but a newer and now recommended way to get data is the following:
public static async Task<dynamic> getDataFromService(string queryString)
{
using (var client = new HttpClient())
{
var responseText = await client.GetStringAsync(queryString);
dynamic data = JsonConvert.DeserializeObject(responseText);
return data;
}
}
Try that and let me know if it works.

HttpClient object method missing

I am separating some code out of a website and after copying the code behind for the particular page in question, I'm getting an error on the PostAsJsonAsync() line of code:
HttpResponseMessage response = await client.PostAsJsonAsync("api/...", user);
which is in this using statement (added headers as well)
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mail;
using System.Threading.Tasks;
//...
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("WebServiceAddress");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.PostAsJsonAsync("api/...", user);
if (response.IsSuccessStatusCode)
{
const string result = "Thank you for your submission.";
return result;
}
//...
}
The error I get says
Error 4 'System.Net.Http.HttpClient'
does not contain a definition for 'PostAsJsonAsync' and no extension
method 'PostAsJsonAsync' accepting a first argument of type 'System.Net.Http.HttpClient'
could be found (are you missing a using directive or an assembly reference?)
even though it works in the former project and was copied straight over from that project in its entirety. Did I forget to add something?
I appreciate any help on the matter.
You will have to add following dependency,
System.Net.Http.Formatting.dll
It should be there in extensions -> assembly.
or
You can add Microsoft.AspNet.WebApi.Client nuget package
I wrote my own extension method as I believe that method is only for older .NET api, and used Newtonsoft JSON serializer:
// Extension method to post a JSON
public static async Task<HttpResponseMessage> PostAsJsonAsync(this HttpClient client, string addr, object obj)
{
var response = await client.PostAsync(addr, new StringContent(
Newtonsoft.Json.JsonConvert.SerializeObject(obj),
Encoding.UTF8, "application/json"));
return response;
}
I had the same error, even with the respective Nuget package installed. What helped me is just this using statement:
using System.Net.Http;

Getting an UTF-8 response with httpclient in Windows Store apps

I'm building a Windows Store app, but I'm stuck at getting a UTF-8 response from an API.
This is the code:
using (HttpClient client = new HttpClient())
{
Uri url = new Uri(BaseUrl + "/me/lists");
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("Accept", "application/json");
HttpResponseMessage response = await client.SendRequestAsync(request);
response.EnsureSuccessStatusCode();
string responseString = await response.Content.ReadAsStringAsync();
response.Dispose();
}
The reponseString always contains strange characters which should be accents like é, and I tried using a stream, but the API I found in some examples don't exist in Windows RT.
Edit: improved code, still same problem.
Instead of using response.Content.ReadAsStringAsync() directly you could use response.Content.ReadAsBufferAsync() pointed by #Kiewic as follows:
var buffer = await response.Content.ReadAsBufferAsync();
var byteArray = buffer.ToArray();
var responseString = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
This is working in my case and I guess that using UTF8 should solve most of the issues. Now go figure why there is no way to do this using ReadAsStringAsync :)
Solved it like this:
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.GetAsync(url))
{
var byteArray = await response.Content.ReadAsByteArrayAsync();
var result = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
return result;
}
}
I like El Marchewko's approach of using an extension, but the code did not work for me. This did:
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace WannaSport.Data.Integration
{
public static class HttpContentExtension
{
public static async Task<string> ReadAsStringUTF8Async(this HttpContent content)
{
return await content.ReadAsStringAsync(Encoding.UTF8);
}
public static async Task<string> ReadAsStringAsync(this HttpContent content, Encoding encoding)
{
using (var reader = new StreamReader((await content.ReadAsStreamAsync()), encoding))
{
return reader.ReadToEnd();
}
}
}
}
Perhaps the problem is that the response is zipped. If the content type is gzip, you will need decompress the response in to a string. Some servers do this to save bandwidth which is normally fine. In .NET Core and probably .NET Framework, this will automatically unzip the response. But this does not work in UWP. This seems like a glaring bug in UWP to me.
string responseString = await response.Content.ReadAsStringAsync();
This thread gives a clear example of how to decompress the response:
Compression/Decompression string with C#
The HttpClient doesn't give you a lot of flexibility.
You can use a HttpWebRequest instead and get the raw bytes from the response using HttpWebResponse.GetResponseStream().
Can't comment yet, so I'll have to add my thoughts here.
You could try to use _client.GetStringAsync(url) as #cremor suggested, and set your authentication headers using the _client.DefaultRequestHeaders property.
Alternatively, you could also try to use the ReadAsByteArrayAsync method on the response.Content object and use System.Text.Encoding to decode that byte array to a UTF-8 string.
My approach using an Extension:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Web.Http;
namespace yourfancyNamespace
{
public static class IHttpContentExtension
{
public static async Task<string> ReadAsStringUTF8Async(this IHttpContent content)
{
return await content.ReadAsStringAsync(Encoding.UTF8);
}
public static async Task<string> ReadAsStringAsync(this IHttpContent content, Encoding encoding)
{
using (TextReader reader = new StreamReader((await content.ReadAsInputStreamAsync()).AsStreamForRead(), encoding))
{
return reader.ReadToEnd();
}
}
}
}

Categories

Resources