I'm trying to check Microsoft Linguistic Analysis API, basic example, so I have subscribed and addad my Key 1 in Ocp-Apim-Subscription-Key and Key 2 into the subscription key here client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");.
Then I add Newtonsoft.Json with Manage NuGet Packages into the References of Application, even it is not listed in using of particular example using Newtonsoft.Json; using bNewtonsoft.Json.Serialization; not sure, I'm new with this tool.
I'm trying to check this example Linguistics API for C# to get some natural language processing results for text analysis mainly of Verb and Noun values according to this example results So I'm not sure if I'm on the right direction with this example, or possible I've missed something to install, maybe I need some additions. I found this Analyze Method not sure how and if I have to use it for this particular goal.
But seems like something is wrong with var queryString = HttpUtility.ParseQueryString(string.Empty); and HttpUtility does not exist.
using System;
using System.Net.Http.Headers;
using System.Text;
using System.Net.Http;
using System.Web;
namespace CSHttpClientSample
{
static class Program
{
static void Main()
{
MakeRequest();
Console.WriteLine("Hit ENTER to exit...");
Console.ReadLine();
}
static async void MakeRequest()
{
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");
var uri = "https://westus.api.cognitive.microsoft.com/linguistics/v1.0/analyze?" + queryString;
HttpResponseMessage response;
// Request body
byte[] byteData = Encoding.UTF8.GetBytes("{body}");
using (var content = new ByteArrayContent(byteData))
{
content.Headers.ContentType = new MediaTypeHeaderValue("< your content type, i.e. application/json >");
response = await client.PostAsync(uri, content);
}
}
}
}
You can create a new writeable instance of HttpValueCollection by calling System.Web.HttpUtility.ParseQueryString(string.Empty), and then use it as any NameValueCollection, like this:
NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(string.Empty);
Try adding a reference to System.Web, and possibly to System.Runtime.Serialization.
Related
Ive removed sensitive data but am getting this issue when trying to make an API request, although I have the relevant packages installed. Why would this be?
using System;
using IronXL;
using RestClient;
using Rest;
using Newtonsoft;
using RestSharp;
using RestSharp.Authenticators;
using RestSharp.Validation;
public static void APIRequest()
{
var client = new RestClient("");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Accept", "application/vnd.evolutionx.v1+json");
request.AddHeader("Authorization", "Bearer ");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
}
This line:
using RestClient;
makes RestClient a known namespace in your code. C# will then assume that any references to RestClient refer to that namespace, unless you specifically say otherwise.
If RestClient really is a class, then you'll have to specify its namespace in front of it
e.g.
new RelevantNamespace.RestClient("")
to differentiate it from the namespace. I would guess it's the RestClient class from RestSharp, so probably new RestSharp.RestClient("") makes sense.
On the other hand, you said in the comments that the RestClient namespace is greyed out in the IDE. This means you are you not using anything from it. Therefore to solve your problem can you can simply remove that using RestClient; statement from your file.
You probably also don't need the RestClient.net package in general, since RestSharp already does a very similar job.
As you're using RestClient.net, it looks like you need to instantiate using
var client = new RestClient.Net.Client();
So the class is Client.
The details of how to setup the class is here:
https://github.com/MelbourneDeveloper/RestClient.Net
Note the how to start
var client = new Client(new NewtonsoftSerializationAdapter(), new Uri("https://restcountries.eu/rest/v2/"));
var response = await client.GetAsync<List<RestCountry>>();
or using .NET Core serialisation
var client = new Client(new Uri("https://restcountries.eu/rest/v2/"));
var response = await client.GetAsync<List<RestCountry>>();
I wrote a little tool to check the availability of a product (yes, the PS5) by checking the products shop page:
var client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("https://www.mediamarkt.de/de/product/_sony-playstation®5-2661938.html");
HttpContent responseContent = response.Content;
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
var output = reader.ReadToEndAsync();
Console.WriteLine(output.Result);
}
For some reason the result page is requesting me to do a captcha while calling the exact same URL in my browser giving me the correct page without captcha.
What is the reason of this behaviour and how do I avoid it?
This is not a direct answer but a workaround
This website is protected by Cloudflare, which shows you recaptcha that only solvable in javascript environment. Obviously, HttpClient does not have such. While there are some solutions for this in other languages, I could not find any for C#. Will show an example in Selenium, web testing framework, that uses web browser driver (in my case Chrome).
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using System;
class Program
{
public static void Main(string[] args)
{
using (var driver = new ChromeDriver())
{
driver.Url = "https://www.mediamarkt.de/de/product/_sony-playstation®5-2661938.html";
// selenium does not behave well when element you are looking for is not visible,
// this method helps us to close cookie banner that blocks the view
CloseCookieBannerIfAppears(driver);
var buyButton = By.XPath("//div[contains(#class, \"Badge\")]").FindElement(driver);
Console.WriteLine(buyButton.Text); // Ausverkauft
}
}
private static void CloseCookieBannerIfAppears(IWebDriver driver)
{
var buttonInAcceptCookieBannerSelector = By.XPath("//button[#id=\"privacy-layer-accept-all-button\"]");
var waitForCookieBanner = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
if (waitForCookieBanner.Until(x => x.FindElements(buttonInAcceptCookieBannerSelector).Count > 0))
{
driver.FindElement(buttonInAcceptCookieBannerSelector)
.Click();
}
}
}
Also looks like they have unprotected API, so you should be able to get this data directly as well. You can see that there is id parameter both in your link and in api call - _sony-playstation®5-2661938.html vs productId=2661938
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
public static async Task Main(string[] args)
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync("https://delivery-prod-teasermanagement.cloud.mmst.eu/api/teaser/find?productId=2661938");
var content = await response.Content.ReadAsStringAsync();
var status = JArray.Parse(content)[0]["promotionData"]["badge"];
Console.WriteLine(status); // Ausverkauft
}
}
Maybe there are some other edge cases, but you should be able to get the point.
I'm pretty new to C# and this is my first time getting data from an api. I was wondering how do I get or call the data collected in this api request (MakeRequest). Preferably assign the data to a public string. The data from the api request is in json format.
using System;
using System.Net.Http.Headers;
using System.Text;
using System.Net.Http;
using System.Web;
namespace CSHttpClientSample
{
public partial class Form1 : Form
{
public async void MakeRequest()
{
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");
// Request parameters
queryString["seasonId"] = "{string}";
var uri = "https://www.haloapi.com/stats/{title}/servicerecords/arena?players={players}&" + queryString;
var response = await client.GetAsync(uri);
}
}
}
So if the call succeeded, you should have your JSON string returned in the response variable you assign in the last line.
Use your debugger and inspect that variable. If you look at the MSDN doc for your GetAsync() method (Link), you can easily find out that the variable is of the type HttpResponseMessage. This class has an own page here telling you that there's a property Content.
This is your JSON string, now might come the part where you have to do some deserializing. Have fun.
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.
I come from an iOS (Swift) background. In one of my Swift apps, I have this class that calls an API. I'm trying to port it to C# (Windows Form application) but I'm hitting several snags. First here's the Swift code. Nothing fancy. One method does a POST request to login to the API and the other function executes a GET method to retrieve the JSON response for a user profile. Both these methods are asynchronous.
import Foundation
class API {
private let session = NSURLSession.sharedSession()
private let baseURL = "https://www.example.com/api/"
func login(userID userID: String, password: String, completion: (error: NSError?) -> ()) {
let url = NSURL(string: baseURL + "login")!
let params = ["username": userID, "password": password]
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.encodeParameters(params) // encodeParameters is an extension method
session.dataTaskWithRequest(request, completionHandler: { data, response, error in
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode != 200 {
completion(error: error)
} else {
completion(error: nil)
}
}
}).resume()
}
func fetchUser(completion: (user: User?, error: NSError?) -> ()) {
let url = NSURL(string: baseURL + "profile")!
let request = NSURLRequest(URL: url)
session.dataTaskWithRequest(request, completionHandler: { data, response, error in
if let error = error {
completion(user: nil, error: error)
} else {
// Parsing JSON
var jsonDict = [String: AnyObject]()
do {
jsonDict = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String: AnyObject]
} catch {
print("Error occurred parsing data: \(error)")
completion(user: nil, error: error)
}
let user = User()
user.name = jsonDict["name"] as! String
user.age = jsonDict["age"] as! Int
completion(user: user, error: nil)
}
}).resume()
}
}
Here's my attempt to convert this to C#.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Http;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Xml.Linq;
using System.Xml.XPath;
namespace MyTrayApp
{
public partial class Form1 : Form
{
private string baseURL = "https://www.example.com/api/";
public Form1()
{
InitializeComponent();
}
private async void Form1_Load(object sender, EventArgs e)
{
await login("myusername", "mypassword");
await fetchUser();
}
async Task login(string userID, string password)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseURL);
var parameters = new Dictionary<string, string>
{
{ "username", userID },
{ "password", password }
};
var encodedParameters = new FormUrlEncodedContent(parameters);
var response = await client.PostAsync("login", encodedParameters);
string responseString = await response.Content.ReadAsStringAsync();
//Console.WriteLine(responseString);
}
}
async Task fetchUser()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseURL);
var response = await client.GetAsync("profile");
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(responseString.ToCharArray()), new System.Xml.XmlDictionaryReaderQuotas());
var root = XElement.Load(jsonReader);
Console.WriteLine(root.XPathSelectElement("//name").Value);
//Console.WriteLine(responseString);
}
}
}
}
These are the problems I'm having.
In my Swift methods, they have completion handlers. How can I do the same in C#?
In Swift, you get an NSData object and you can pass it to NSJSONSerialization to create a JSON object. In my current implementation, I get an XML exception at XElement.Load(jsonReader);. I'm not sure if this is the correct way to do this even. I found tons of different solutions here on SO. But some are for Metro apps, some are for web it's all too overwhelming. Also most solutions are on using third-party libraries like JSON.NET. I'm trying to achieve this without third-party libraries.
In my Swift methods, they have completion handlers. How can I do the
same in C#?
The point of wiring up a completion handler is so that you don't tie up a thread while waiting for the HTTP call to complete. The beauty of async/await is that you don't have to do this in C#. The await keyword instructs the compiler to literally rewrite the rest of the method as a callback. The current thread is freed as soon as await is encountered, preventing your UI from freezing up. You have written your async code correctly; it will behave asynchronously even though it looks synchronous.
Your second question is a bit broad, but I will make 2 suggestions:
Don't use XElement when dealing with JSON data. That part of an Microsoft's XML parsing library (one of them) and has nothing to do with JSON.
I'm not sure why achieving this without a 3rd-party library is important. I know people have their reasons, but Json.NET in particular has become so popular and ubiquitous that Microsoft itself has baked it into their ASP.NET MVC and Web API frameworks. That said, if you must avoid it, here is how you would deserialize JSON using only Microsoft libraries.