I'm using HttpWebRequests to contact an API and need to add a header but the compiler tells me that the method does not exists.
Yet, when I check MSDN, it tells me that the method already exists.
Setting my UserAgent-property fails as well.
Can anyone help me please?
try{
HttpWebRequest wr = (HttpWebRequest)HttpWebRequest.Create(url);
wr.Method = "GET";
wr.Headers.Add(System.Net.HttpRequestHeader.Authorization, string.Format("Bearer {0}", _accessToken));
wr.UserAgent = _appNameAndContact;
var resp = (System.Net.HttpWebResponse) await wr.BetterGetResponse();
if (resp.StatusCode == System.Net.HttpStatusCode.OK)
{
using (var sw = new System.IO.StreamReader(resp.GetResponseStream()))
{
var msg = sw.ReadToEnd();
User usr = JsonConvert.DeserializeObject<User>(msg);
//var results = JSONHelper.Deserialize<User>(msg);
return usr;
}
}
}
You will have to use a HttpRequestMessage like this:
using (var httpClient = new HttpClient())
{
var url = new Uri("http://bing.com");
var accessToken = "1234";
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url))
{
httpRequestMessage.Headers.Add(System.Net.HttpRequestHeader.Authorization.ToString(),
string.Format("Bearer {0}", accessToken));
httpRequestMessage.Headers.Add("User-Agent", "My user-Agent");
using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage))
{
// do something with the response
var data = httpRequestMessage.Content;
}
}
}
Related
I'm trying send a JSON file with postman and it's working. But when I'm trying to send the same contents via HttpClient it's not working.
System.IO.File.WriteAllText(dirName + "\\importproduct.json", jsonitems);
var fileByteArray = File.ReadAllBytes(dirName + "\\importproduct.json");
using (var _client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
content.Add(new StreamContent(new MemoryStream(fileByteArray)), "file");
var url = $"{firmInfo.ServiceUrl}/product/api/products/import";
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearer_token.id_token);
var response = _client.PostAsJsonAsync(url, content).Result;
var result = response.Content.ReadAsStringAsync().Result;
}
}
PostMan:
Instead of using PostAsJsonAsync(); method you should use PostAsync(); So your code should be looking something like that
using (var _client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
content.Add(new StreamContent(new MemoryStream(fileByteArray)), "file");
var url = $"{firmInfo.ServiceUrl}/product/api/products/import";
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearer_token.id_token);
var response = _client.PostAsync(url, content).Result;
var result = response.Content.ReadAsStringAsync().Result;
}
}
PostAsJsonAsync method is a generic method, it expects as the second parameter the object that will be serialized and sent in the POST body.
var obj = JsonConvert.DeserializeObject<SomeModelClass>(jsonString);
var response = await _client.PostAsJsonAsync(url, obj).Result;
This is based on efecetir's post above. It works for me. BTW, I also upvoted his post.
My issue was I needed to set the content type at the content-based level.
var fileByteArray = File.ReadAllBytes(filePath);
HttpContent bytesContent = new ByteArrayContent(fileByteArray);
using (var httpClient = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
var RequestUri = new Uri($"http://whatever.com/");
//client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearer_token.id_token);
formData.Headers.Add("super-secret-key", "blah");
bytesContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
//httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //("multipart/form-data")); // Not needed
formData.Add(bytesContent, "file", "blah.json");
var response = httpClient.PostAsync(RequestUri, formData).Result;
return await HandleResponse(response);
}
Thanks for your comments.
I fixed it and convert my codes as below. Now it's working and much more clean.
HttpContent bytesContent = new ByteArrayContent(fileByteArray);
using (var client = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
var url = $"{firmInfo.ServiceUrl}/product/api/products/import";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearer_token.id_token);
formData.Add(bytesContent, "file", "importproduct.json");
var response = client.PostAsync(url, formData).Result;
var result = response.Content.ReadAsStringAsync().Result;
}
Here's code I'm using to post form information and a file
using (var httpClient = new HttpClient())
{
var surveyBytes = ConvertToByteArray(surveyResponse);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var byteArrayContent = new ByteArrayContent(surveyBytes);
byteArrayContent.Headers.ContentType = MediaTypeHeaderValue.Parse("text/csv");
var url = $"{firmInfo.ServiceUrl}/product/api/products/import";
var response = await httpClient.PostAsync(url , new MultipartFormDataContent
{
{byteArrayContent, "\"file\"", dirName + "\\importproduct.json"}
});
return response;
}
This is for .net 4.5.
The following code reports "error: unauthenticated".
How can I use .NET to authenticate against this Comcast/Xfinity API to query/fetch used and available data of an account with a monthly quota?
static async Task Main() {
using (var httpClient = new HttpClient()) {
using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://customer.xfinity.com/apis/services/internet/usage")) {
var response = await httpClient.SendAsync(request);
var responseStream = await response.Content.ReadAsStreamAsync();
var streamReader = new StreamReader(responseStream, Encoding.UTF8);
var responseContent = streamReader.ReadToEnd(); // {"error":"unauthenticated"}
}
}
}
Figured it out. This code runs in either .NET Framework (tested 4.7.1) or .NET Core (tested 2.2). It authenticates with otherwise-defined Username and Password values and prints the data used and the data remaining in the month.
static async Task Main() {
using (var httpClient = new HttpClient()) {
double totalUsage;
double allowableUsage;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // this line can be removed in .NET Core
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://login.xfinity.com/login")) {
var data = new Dictionary<string, string> {
{"user", Username}
, {"passwd", Password}
, {"s", "oauth"}
, {"continue", "https://oauth.xfinity.com/oauth/authorize?client_id=my-account-web&prompt=login&redirect_uri=https%3A%2F%2Fcustomer.xfinity.com%2Foauth%2Fcallback&response_type=code"}
};
var content = string.Join("&", data.Select(x => $"{x.Key}={WebUtility.UrlEncode(x.Value)}"));
request.Content = new StringContent(content, Encoding.UTF8, "application/x-www-form-urlencoded");
await httpClient.SendAsync(request);
}
using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://customer.xfinity.com/apis/services/internet/usage")) {
var response = await httpClient.SendAsync(request);
var responseStream = await response.Content.ReadAsStreamAsync();
var streamReader = new StreamReader(responseStream);
var responseContent = streamReader.ReadToEnd();
var parsedResponse = JObject.Parse(responseContent);
var usageMonths = parsedResponse["usageMonths"];
var currentMonthUsage = usageMonths.Last;
totalUsage = currentMonthUsage.Value<double?>("totalUsage") ?? 0;
allowableUsage = currentMonthUsage.Value<double?>("allowableUsage") ?? 0;
}
Console.WriteLine($"Allowable: {allowableUsage}");
Console.WriteLine($"Total : {totalUsage}");
Console.ReadKey();
}
}
Depends on nuget.org/packages/Newtonsoft.Json/12.0.1
please, help me with POST api request in C#.I dont know how to correctly send parameters „key“, „signature“ and „nonce“ in POST request. It constantly tells me "Missing key, signature and nonce parameters“.
HttpWebRequest webRequest =(HttpWebRequest)System.Net.WebRequest.Create("https://www.bitstamp.net/api/balance/");
if (webRequest != null)
{
webRequest.Method = HttpMethod.Post;
webRequest.ContentType = "application/json";
webRequest.UserAgent = "BitstampBot";
byte[] data = Convert.FromBase64String(apisecret);
string nonce = GetNonce().ToString();
var prehash = nonce + custID + apikey;
string signature = HashString(prehash, data);
body = Serialize(new
{
key=apikey,
signature=signature,
nonce=nonce
});
if (!string.IsNullOrEmpty(body))
{
var data1 = Encoding.UTF8.GetBytes(body);
webRequest.ContentLength = data1.Length;
using (var stream = webRequest.GetRequestStream()) stream.Write(data1, 0, data1.Length);
}
using (Stream s = webRequest.GetResponse().GetResponseStream())
{
using (StreamReader sr = new System.IO.StreamReader(s))
{
contentBody = await sr.ReadToEndAsync();
return contentBody;
}
}
}
The "Request parameters" as Bitstamp specifies in the docs is actually supposed to be sent with content type "application/x-www-form-urlencoded" instead of "application/json".
I would also use HttpClient to perform the post as that has a much more simple setup to perform Http requests
using (var client = new HttpClient())
{
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("key", apikey),
new KeyValuePair<string, string>("signature", signature),
new KeyValuePair<string, string>("nonce", nonce)
});
var result = await client.PostAsync("https://www.bitstamp.net/api/balance/", content);
string resultContent = await result.Content.ReadAsStringAsync();
}
I need to postAsync with header and content together. In order to get access to a website through Console Application in C#. I have my headers as an HttpHeader object with variable name header and my content named newContent as a string object with __Token, return, Email and Password. Now what I want to do is add newContent to header and then use postAsync(url, header+content) to make my POST request.
public async static void DownloadPage(string url)
{
CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = cookies;
using (HttpClient client = new HttpClient(handler))
{
using (HttpResponseMessage response = client.GetAsync(url).Result)
{
//statusCode
CheckStatusCode(response);
//header
HttpHeaders headers = response.Headers;
//content
HttpContent content = response.Content;
//getRequestVerificationToken&createCollection
string newcontent = CreateCollection(content);
using(HttpResponseMessage response2 = client.PostAsync(url,))
}
}
}
public static string GenerateQueryString(NameValueCollection collection)
{
var array = (from key in collection.AllKeys
from value in collection.GetValues(key)
select string.Format("{0}={1}", WebUtility.UrlEncode(key), WebUtility.UrlEncode(value))).ToArray();
return string.Join("&", array);
}
public static void CheckStatusCode(HttpResponseMessage response)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.ReasonPhrase));
else
Console.WriteLine("200");
}
public static string CreateCollection(HttpContent content)
{
var myContent = content.ReadAsStringAsync().Result;
HtmlNode.ElementsFlags.Remove("form");
string html = myContent;
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var input = doc.DocumentNode.SelectSingleNode("//*[#name='__Token']");
var token = input.Attributes["value"].Value;
//add all necessary component to collection
NameValueCollection collection = new NameValueCollection();
collection.Add("__Token", token);
collection.Add("return", "");
collection.Add("Email", "11111111#hotmail.com");
collection.Add("Password", "1234");
var newCollection = GenerateQueryString(collection);
return newCollection;
}
I did the very same thing yesterday. I created a seperate class for my Console App and put the HttpClient stuff in there.
In Main:
_httpCode = theClient.Post(_response, theClient.auth_bearer_token);
In the class:
public long Post_RedeemVoucher(Response _response, string token)
{
string client_URL_voucher_redeem = "https://myurl";
string body = "mypostBody";
Task<Response> content = Post(null, client_URL_voucher_redeem, token, body);
if (content.Exception == null)
{
return 200;
}
else
return -1;
}
Then the call itself:
async Task<Response> Post(string headers, string URL, string token, string body)
{
Response _response = new Response();
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URL);
request.Content = new StringContent(body);
using (HttpResponseMessage response = await client.SendAsync(request))
{
if (!response.IsSuccessStatusCode)
{
_response.error = response.ReasonPhrase;
_response.statusCode = response.StatusCode;
return _response;
}
_response.statusCode = response.StatusCode;
_response.httpCode = (long)response.StatusCode;
using (HttpContent content = response.Content)
{
_response.JSON = await content.ReadAsStringAsync().ConfigureAwait(false);
return _response;
}
}
}
}
catch (Exception ex)
{
_response.ex = ex;
return _response;
}
}
I hope this points you in he right direction!
How about iterating over your Headers and adding them to the Content object:
var content = new StringContent(requestString, Encoding.UTF8);
// Iterate over current headers, as you can't set `Headers` property, only `.Add()` to the object.
foreach (var header in httpHeaders) {
content.Headers.Add(header.Key, header.Value.ToString());
}
response = client.PostAsync(Url, content).Result;
Now, they're sent in one method.
If you are still looking into this you can also add headers at the request level as well as the HttpClient level. This works for me:
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URL);
request.Content = new StringContent(body);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
The gitWebRequest.GetResponse() line is returning a 403 error from the server and I can't seem to figure out why. Any help appreciated.
var address = new Uri(verifyUrl + _apiKey);
HttpRequest request = HttpContext.Current.Request;
var gitWebRequest = WebRequest.Create(address) as HttpWebRequest;
gitWebRequest.Method = "POST";
gitWebRequest.ContentType = "application/json";
var requestReader = new StreamReader(request.InputStream);
var requestBody = requestReader.ReadToEnd();
var myRequestUri = string.Format("{0}://{1}{2}",request.Url.Scheme,request.Url.Authority.TrimEnd('/'), request.RawUrl);
var verifyRequestData = new { requestUri = myRequestUri, postBody = requestBody };
var gitRequestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(verifyRequestData));
using (var stream = gitWebRequest.GetRequestStream())
{
stream.Write(gitRequestData, 0, gitRequestData.Length);
}
using (var response = gitWebRequest.GetResponse() as HttpWebResponse)
{
// Get the response stream
if (response != null)
{
var responseReader = new StreamReader(response.GetResponseStream());
result = responseReader.ReadToEnd();
}
}
It was using http instead of https, which is what goole requires.
Thanks for making me look at the url.