Because of Net 6.0 usage I'm frustrated how to convert old HttpWebResponse to httpClient
Could someone help me to handle it right?
I have httpClient request
var handler = new HttpClientHandler();
if (handler.SupportsAutomaticDecompression)
{
handler.AutomaticDecompression = DecompressionMethods.GZip |
DecompressionMethods.Deflate;
}
var httpClient = new HttpClient(handler);
httpClient.SendAsync(new HttpRequestMessage(new HttpMethod.Post, url));
And I have old HttpWebResponse
using (var dataStream = httpWebRequest.GetRequestStream())
{
var reqDataByte = Encoding.GetEncoding(encoding).GetBytes(reqData);
dataStream.Write(reqDataByte, 0, reqDataByte.Length);
}
using (var httpWebResponse = (HttpWebResponse) httpWebRequest.GetResponse())
{
var responseStream = httpWebResponse.GetResponseStream();
if (responseStream != null)
using (var streamReader =
new StreamReader(responseStream, Encoding.GetEncoding(encoding)))
{
getString = streamReader.ReadToEnd();
}
}
Couldn't understand how to handle respond with httpClient right
using var dataStream = httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
var reqDataByte = Encoding.GetEncoding(encoding).GetBytes(reqData);
dataStream.CopyToAsync(reqDataByte, 0, reqDataByte.Length);
using var response = (HttpWebResponse) httpClient.GetResponse();
var responseStream = response.GetResponseStream();
using var streamReader =
new StreamReader(responseStream, Encoding.GetEncoding(encoding));
getString = streamReader.ReadToEnd();
If you are trying to simply post raw bytes and get a string response back it is quite simple. You will need this to be an async method and await the async calls.
var reqDataByte = Encoding.GetEncoding(encoding).GetBytes(reqData);
var response = await httpClient.PostAsync(url, new ByteArrayContent(reqDataByte));
if (response.IsSuccessStatusCode)
{
getString = await response.Content.ReadAsStringAsync();
}
else
{
//Handle any unsuccessful post
}
Related
When I tried this code in a normal Console app project it works, but it doesnt work on xamarin, the exception occurs in
" using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
"
string html = string.Empty;
string url = $"https://stackoverflow.com/";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AutomaticDecompression = DecompressionMethods.GZip;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
html = reader.ReadToEnd();
}
I'd suggest trying HttpClient instead
var client = new HttpClient();
var response = await client.GetAsync("http://www.contoso.com/");
string responseBody = await response.Content.ReadAsStringAsync();
I am trying to execute a REST API which uses HTTP POST. The API consumes and produces xml content. I am getting null in httpResponseMessage and no exception is thrown. I tried executing the same REST API through HttpWebRequest I am getting the response Below you can find Working and Not Working case. Performance wise HttpWebRequest or HTTPClient which is better ?
Not Working case HTTPClient
try {
using(var client = new HttpClient()) {
Console.WriteLine(inputxml);
var httpContent = new StringContent(inputxml, Encoding.UTF8, "application/xml");
Uri testUri = new Uri("http://127.0.0.1:8080/rest/services/getDocument");
var httpResponseMessage = await client.PostAsync(testUri, httpContent);
Console.WriteLine(httpResponseMessage.Content.ReadAsStringAsync());
if (httpResponseMessage.StatusCode == HttpStatusCode.OK) {
var messageContents = await httpResponseMessage.Content.ReadAsStringAsync();
}
}
}
Working Case HTTPWebREquest
HttpWebRequest request = (HttpWebRequest) WebRequest.Create("http://127.0.0.1:8080/rest/services/getDocument");
byte[] bytes = Encoding.UTF8.GetBytes(inputxml.ToString());
request.ContentType = "application/xml";
request.ContentLength = bytes.Length;
request.Method = "POST";
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
HttpWebResponse response;
response = (HttpWebResponse) request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK) {
Stream responseStream = response.GetResponseStream();
string responseStr = new StreamReader(responseStream).ReadToEnd();
Console.WriteLine("responseStr " + responseStr);
return responseStr;
}
return null;
}
Here:
Console.WriteLine(httpResponseMessage.Content.ReadAsStringAsync());
You're reading the response body, and printing System.Threading.Task1` to the console. Then the next time you try to read the response body again, its stream is at its end and won't return anything.
Read the content once, await the call and store the result in a variable.
You can use RestSharp for sending HTTP Requests.
For me, the best and the simplest method for HTTP Communication.
public string SendRequest(String xml)
{
string responseMessage= "";
RestClient restClient;
restClient = new RestClient("http://127.0.0.1:8080/rest/services/getDocument");
RestRequest restRequest = new RestRequest(Method.POST);
restRequest.AddHeader("Accept", "application/xml");
restRequest.AddHeader("Content-Type", "application/xml");
restRequest.AddXmlBody(xml);
IRestResponse restResponse = restClient.Execute(restRequest);
if (restResponse.StatusCode == HttpStatusCode.OK)
{
responseMessage= restResponse.Content;
}
return responseMessage;
}
}
I am dealing with a third-party API which insists on a binary File Upload request being formatted without a Content-Type header value of multipart/form-data, and with the following headers:
Content-Type: application/octet-stream
Content-Disposition: filename*=UTF-8''file.zip
HttpRequestMessage and HttpContent.Headers.ContentDisposition.DispositionType won't allow me to achieve this either because I can't set the values as desired or they set them automatically.
I accept that this API may not be following HTTP Standards but it's not mine and I have no influence over it.
My attempt which does not work
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.ExpectContinue = false;
FileStream fs = new FileStream(#"e:\dev\TestHalfB.docx", FileMode.Open);
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, <Uri>);
HttpContent fc = new StreamContent(fs);
var mpContent = new MultipartFormDataContent();
mpContent.Add(fc);
fc.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
req.Content = fc;
fc.Headers.ContentDisposition.DispositionType = "filename*=UTF-8''TestHalfB.docx";
using (var response = await client.SendAsync(req))
{
response.EnsureSuccessStatusCode();
var resp = await response.Content.ReadAsStringAsync();
}
fs.Close();
}
Does anyone know of a lower level API I could use or have any suggestions?
So the crux is how can I set the Content-Disposition header to the value I desire.
I had to switch to using WebRequest.
WebRequest request = WebRequest.Create("https://cloud.memsource.com/web/api2/v1/projects/{id}/jobs?token={token}");
request.Method = "POST";
byte[] byteArray = File.ReadAllBytes(#"E:\Dev\TestHalfB.docx");
request.ContentType = "application/octet-stream";
request.ContentLength = byteArray.Length;
request.Headers.Add("Content-Disposition", "filename*=UTF-8''TestHalfB.docx");
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
((HttpWebResponse)response).StatusDescription.Dump();
Could you please try this.
HttpContent fileStreamContent = new StreamContent(paramFileStream);
using (var formData = new MultipartFormDataContent())
{
formData.Add(fileStreamContent, "file1", "file1");
var response = client.PostAsync(actionUrl, formData).Result;
}
This should work for you (or at least get you started, since it's not tested):
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, <Uri>);
using (FileStream fs = new FileStream(#"e:\dev\TestHalfB.docx", FileMode.Open))
{
byte[] fb = new byte[(int)fs.Length]; // assumes your file size will fit into an int
await fs.ReadAsync(fb, 0, (int)fs.Length);
req.Content = new ByteArrayContent(fb);
req.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
req.Content.Headers.ContentDisposition.FileNameStar = "UTF-8''TestHalfB.docx";
using (var response = await client.SendAsync(req))
{
response.EnsureSuccessStatusCode();
var resp = await response.Content.ReadAsStringAsync();
}
}
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
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.