Since WebClient is deprecated in .NET 6, what is the best solution to convert the following code using WebClient with an equivalent code using HttpClient?
byte[] data = Converter(...); // object to zipped json string
var client = new WebClient();
client.Headers.Add("Accept", "application/json");
client.Headers.Add("Content-Type", "application/json; charset=utf-8");
client.Headers.Add("Content-Encoding", "gzip");
client.Encoding = Encoding.UTF8;
byte[] response = webClient.UploadData("...url...", "POST", data);
string body = Encoding.UTF8.GetString(response);
This code works but only accepts simple json strings as input:
var request = new HttpRequestMessage()
{
RequestUri = new Uri("...url..."),
Version = HttpVersion.Version20,
Method = HttpMethod.Post,
Content = new StringContent("...json string...", Encoding.UTF8, "application/json");
};
var client = new HttpClient();
var response = client.SendAsync(request).Result;
I need a solution to post a zipped json string.
Thank you!
No surprise you managed to only send simple strings, because you used StringContent, which is meant for (drum roll!) string content.
So, what to do if you want to send binary data in form of a byte array? Well, the answer is simple: Don't use StringContent. Instead, use (drum roll intensifies) ByteArrayContent.
In order to add content type you could do this:
var content = new StringContent(payload, Encoding.UTF8);
content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");
If you want to add headers like you did with webclient:
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//OR
var header = new KeyValuePair<string, string>(key: "Accept", value: "application/json");
client.DefaultRequestHeaders.Add(header.Key, header.Value));
Related
Need to pass Json Content in Request body using http client DeleAsync Method in C#.Not able to pass the Request body in DeleteAsync Method.
HttpClient client=new HttpClient();
var Ids = new[] { 100,202,304,866 };
string endpoint=" URL goes here";
string jsonString = JsonConvert.SerializeObject(Ids);
var RequestBody = new StringContent(jsonString, Encoding.UTF8);
var response = client.DeleteAsync(endpoint,RequestBody).Result;
You can do like this. As far as I know you can't have body in DeleteAsync
object jsonObj;
using (HttpClient client = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Delete,
RequestUri = new Uri("yourUrl"),
Content = new StringContent(JsonConvert.SerializeObject(jsonObj), Encoding.UTF8, "application/json")
};
var response = await client.SendAsync(request);
I am New in C#.
I want to send JSON request body in POST request using C#.
I want To get results from Rest URL but it's showing me status code 500.
How can I format the request body so that I able to get results from the rest URL?
My Request body in JSON -->
{"filter":{"labtestName":[{"labtestName":"Ada"}]}}
code that I tried
string data1 = "{\filter\":{\"labtestName\":[{\"labtestName\":\"Ada\"}]}}";
var RestURL = "https://nort.co.net/v1api/LabTest/Hurlabtest";
HttpClient client = new HttpClient();
string jsonData = JsonConvert.SerializeObject(data1);
client.BaseAddress = new Uri(RestURL);
StringContent content1 = new StringContent(jsonData, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Add("apptoken", "72f303a7-f1f0-45a0-ad2b-e6db29328b1a");
client.DefaultRequestHeaders.Add("usertoken", "cZJqFMitFdVz5MOvRLT7baVTJa+yZffc5eVoU91OqkMYl6//cQmgIVkHOyRZ7rWTXi66WV4tMEuj+0oHIyPS6hBvPUY5/RJ7oWnTr4LuzlKU1H7Cp68za57O9AatAJJHiVPowlXwoPUohqe8Ad2u0A==");
HttpResponseMessage response = await client.PostAsync(RestURL, content1);
var result = await response.Content.ReadAsStringAsync();
var responseData = JsonConvert.DeserializeObject<LabtestResponseData>(result);
You are sending the wrong data to the method,
I have corrected it, you can refer to the below code.
myData string is already a JSON string so there is no need to serialize it again.
string myData = "{\"filter\": {\"labtestName\": [{\"labtestName\": \"Ada\"}]}}";
//string data1 = "{\filter\": {\"labtestName\": [{\"labtestName\": \"Ada\"}]}}";
var RestURL = "https://tcdevapi.iworktech.net/v1api/LabTest/HSCLabTests";
HttpClient client = new HttpClient();
//string jsonData = JsonConvert.SerializeObject(myData);
client.BaseAddress = new Uri(RestURL);
StringContent content1 = new StringContent(myData, Encoding.UTF8, "application/json");
I tried to make HTTP POST request with application/json in body to an external web-service from C# (.NET Core 2.2.104).
I've already read all similar questions in SO and wrote this code:
SignXmlRequestDto requestBody = new SignXmlRequestDto(p12, model.SignCertPin, model.Data);
string json = JsonConvert.SerializeObject(requestBody);
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = ncanNodeUrl,
Headers =
{
{ HttpRequestHeader.ContentType.ToString(), "application/json" }
},
Content = new StringContent(JsonConvert.SerializeObject(json))
};
var response = await httpClient.SendAsync(httpRequestMessage);
string responseString = await response.Content.ReadAsStringAsync();
I am getting an error from service, it says: "Invalid header Content-Type. Please set Content-Type to application/json". What is interesting here, if I simulate this request from Postman, then everything work well and I get successful response.
Updated: as #Kristóf Tóth suggested, I modified my code to:
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = ncanNodeUrl,
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
var response = await httpClient.SendAsync(httpRequestMessage);
string responseString = await response.Content.ReadAsStringAsync();
but it still gives me the same error message.
Content-Type is a content header. It should be set on the content, not the request itself. This can be done either using the StringContent(string,Encoding,string) constructor :
Content = new StringContent(JsonConvert.SerializeObject(json),Encoding.UTF8, "application/json")
or by setting the StringContent's Headers.ContentType property :
var content=new StringContent(JsonConvert.SerializeObject(json));
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
This might be an encoding issue. You should use JsonContent not StringContent OR you can do something similar:
// Serialize into JSON String
var stringPayload = JsonConvert.SerializeObject(payload);
// Wrap JSON StringContent which then can be used by the HttpClient class
var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json");
How exactly do I use the enhanced AMD through Twilio? I understand that it can only be done through the REST API (no TwiML) but I'm having a hard time seeing the connection between a standard call and the answering machine detection.
I've read through this page a few times, but I still don't understand. So here is the standard c# code for placing a call through the REST API:
TwilioClient.Init(AccountSid, AuthToken);
var to = new PhoneNumber("+14155551212");
var from = new PhoneNumber("+15017250604");
var call = CallResource.Create(to, from, url: new Uri("http://demo.twilio.com/docs/voice.xml"));
And here is my c# translated code from the aforementioned link:
using (var client = new HttpClient())
{
var byteArray = Encoding.ASCII.GetBytes($#"{AccountSid}:{AuthToken}");
var header = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
client.DefaultRequestHeaders.Authorization = header;
var requestContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("To", "+15017250604"),
new KeyValuePair<string, string>("From", "+15017250604"),
new KeyValuePair<string, string>("MachineDetection", "DetectMessageEnd"),
new KeyValuePair<string, string>("Url", Url.Action("PostTransfer"))
});
var response = client.PostAsync(_amdRequest, requestContent);
var responseContent = response.Result.Content;
}
So what am I missing? I'm sure it's something simple, but I'm not seeing how the enhanced AMD knows what call to listen to, and what the order of events here should be. And finally, how am I supposed to see the results?
EDIT:
So to be crystal clear, here is my code as it currently sits:
TwilioClient.Init(AccountSid, AuthToken);
var toPhone = new PhoneNumber(to);
var fromPhone = new PhoneNumber(from);
var call = CallResource.Create(toPhone, fromPhone, url: new Uri("http://demo.twilio.com/docs/voice.xml"));
using (var client = new HttpClient())
{
var byteArray = Encoding.ASCII.GetBytes($#"{AccountSid}:{AuthToken}");
var header = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
client.DefaultRequestHeaders.Authorization = header;
var requestContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("To", to),
new KeyValuePair<string, string>("From", from),
new KeyValuePair<string, string>("MachineDetection", "DetectMessageEnd"),
new KeyValuePair<string, string>("Url", Url.Action("PostTransfer"))
});
var response = client.PostAsync(_amdRequest, requestContent);
var responseContent = response.Result.Content;
}
And elsewhere in my code is a function called "PostTransfer" that gets the "AnsweredBy" parameter and does some stuff after the call is placed. Should this be working? Because it isn't. The call goes through and I can hear Twilio's example file play, but it never gets to the "PostTransfer" function.
Twilio developer evangelist here.
You look like you're making a call with detection successfully. You're making a call from your Twilio number to a users number.
You see the results of the answering machine detection when Twilio has decided on whether it is a machine or a human, at which point it makes a webhook request to your URL that you send as part of making the call.
When Twilio makes the webhook, it will include an extra parameter: AnsweredBy. When you set MachineDetection to DetectMessageEnd the values of AnsweredBy can be: machine_end_beep, machine_end_silence, machine_end_other, human, fax, and unknown. You can then read this value and decide what to do with the call at this point.
Does that help at all?
Can you try HttpWebRequest instead? here is an example how to do it,
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "POST";
request.Headers.Add("Authorization", string.Format("Bearer {0}",AccessToken));
request.ContentType = "application/json;charset=utf-8";
request.ContentLength = body.Length;
request.Accept = "application/json"
if (!string.IsNullOrWhiteSpace(body))
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] bytes = encoding.GetBytes(body);
request.ContentLength = bytes.Length;
using (Stream requestStream = request.GetRequestStream())
{
// Send the data.
requestStream.Write(bytes, 0, bytes.Length);
}
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if (callback != null)
{
var reader = new StreamReader(response.GetResponseStream());
callback(reader.ReadToEnd());
}
}
I have already encoded data that wants to pass as is the String to HttpClient PostRequest
but FormUrlEncodedContent only accepts a dictonary as parameter
I want something like client.PostAsync(url, plain_string_content)
var content = new FormUrlEncodedContent(values);
using (var client = new HttpClient())
{
try
{
var response = client.PostAsync(url, content).GetAwaiter().GetResult();
string resp=response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
return resp;
}
You may use HttpClient.SendAsync:
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post);
request.Content = new StringContent(plain_string_content);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
await client.SendAsync(request);
Note that, after all, PostAsync and other HttpClient's methods are shortcuts of SendAsync.