How to pass content-type in http client using C#? - dotnet-httpclient

How to pass below content-type in http client using C# ?
multipart/alternative;
boundary=56CC414C-FDE6-48DB-846C-6A1CEBCD7805;
type=\"text/plain\"

Something like this should work,
var multipartContent = new MultipartContent("alternative","56CC414C-FDE6-48DB-846C-6A1CEBCD7805");
multipartContent.Add(new StringContent("Here is some content"));
var httpClient = new HttpClient();
httpClient.PostAsync("http://example.org/",multipartContent);

Related

How do I can iterate cookie values from http response?

I am using rest API in my flutter app. For further request I need JSESSIONID which I received from my profile API. I successful got response but I need guide to iterate cookie value.
I followed following steps:
final response = await http.get(
strURL,
headers: {
"Authorization": basicAuth,
"Content-Type": "application/json"
},
);
String rawCookie = response.headers['set-cookie'];
print('rawCookie $rawCookie');
As print raw cookie it is printing details:
flutter: rawCookie __cfduid=d5bbe3f8a131478a78ae996e636cca0401544177738; expires=Sat, 07-Dec-19 10:15:38 GMT; path=/; domain=.rayz.ch; HttpOnly,JSESSIONID=6AD6698C5BFC90F1D089696A955E6824; Path=/; HttpOnly
I can iterate it by substring but I want to iterate it with a proper way. So please guide me on this.
With package:http you need to split the cookie string yourself using String.split. If you want to use the underlying http client, that gives you a pre-parsed list of cookies, for example:
HttpClient _httpClient = new HttpClient();
HttpClientRequest request = await _httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
print(response.cookies); // this is a List<Cookie>
Here is my code which runs perfectly and if any key does not have value, then it shows range error. But as your doubt, this code is running fine.
var headersList = response.headers['set-cookie']!.split(";");
for(var kvPair in headersList){
var kv = kvPair.split("=");
var key = kv[0];
var value = kv[1];
if(key.contains("session_id")){
print(value);
}
}

UCWA 2.0 Trying to add forward contact but getting ParameterValidationFailure

I am using UCWA 2.0 for some Skype4Business integration in our intranet web application.
I can successfully connect and do some stuff for example: changing availability status or asking for callforwarding settings of the user.
What I like to do that does not work is set a forward contact for the user.
Documentation for this: click here
My code for the POST call:
using (var client = new HttpClient())
{
var param = new { target = "sip:user#domain.be" };
var paramJson = JsonConvert.SerializeObject(param, Formatting.Indented);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Referrer = new Uri(result4._links.xframe.href);
client.DefaultRequestHeaders.Add("Authorization", $"{result3.token_type} {result3.access_token}");
var url = $"https://ucwebext.domain.be/{applicationUrl}/me/callForwardingSettings/immediateForwardSettings/immediateForwardToContact";
var responseNew = await client.PostAsync(url, new StringContent(paramJson, Encoding.UTF8, "application/json"));
var responseString = await responseNew.Content.ReadAsStringAsync();
}
Same code using RestSharp:
var client = new RestClient($"https://ucwebext.domain.be/{applicationUrl}");
var restR = new RestRequest("/me/callForwardingSettings/immediateForwardSettings/immediateForwardToContact", Method.POST);
var param = new { target = "sip:user#domain.be" };
var jsonToSend = JsonConvert.SerializeObject(param, Formatting.Indented);
restR.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
restR.AddParameter("referer", result4._links.xframe.href);
restR.AddHeader("Authorization", $"{result3.token_type} {result3.access_token}");
restR.RequestFormat = DataFormat.Json;
var response = client.ExecuteAsPost(restR, "POST");
Request header from the call:
POST https://ucwebext.domain.be/ucwa/oauth/v1/applications/101024253230/me/callForwardingSettings/immediateForwardSettings/immediateForwardToContact HTTP/1.1
Accept: application/json
Referer: https://ucwebext.domain.be/Autodiscover/XFrame/XFrame.html
Authorization: Bearer cwt=AAEBHAEFAAAAAAAF...0Q_OXzsR4g4F-PpYaMGK10Pg
Content-Type: application/json; charset=utf-8
Host: ucwebext.domain.be
Content-Length: 48
Expect: 100-continue
{"target":"sip:user#domain.be"}
I get the following error:
{"code":"BadRequest","subcode":"ParameterValidationFailure","message":"Please check what you entered and try again.","parameters":[{"name":"target","reason":"MissingOrInvalid"}]}
I tried everything and don't understand why the parameter is not submitting or invalid.
Any help is much appreciated!
SOLUTION
Instead of using JSON I added the parameter as querystring which worked!
var client = new RestClient($"https://ucwebext.domain.be/{applicationUrl}");
var restR = new RestRequest($"/me/callForwardingSettings/immediateForwardSettings/immediateForwardToContact{Url.Encode("?target=sip:user#domain.be")}", Method.POST);
restR.AddParameter("referer", result4._links.xframe.href);
restR.AddHeader("Authorization", $"{result3.token_type} {result3.access_token}");
var response = client.ExecuteAsPost(restR, "POST");

RestTemplate upload image as MultipartFile with Content-Type image/jpg

I am trying to upload an image (MultipartFile) using RestTemplate to a server URL.
Sending request from postman works with Content-Type: image/jpg and an image sent as Binary File from Body.
Method implementation in SpringBoot:
public ResponseEntity<String> uploadImage(MultipartFile file) {
restTemplate.getMessageConverters().add(new ByteArrayHttpMessageConverter());
restTemplate.getMessageConverters().add(new BufferedImageHttpMessageConverter());
LinkedMultiValueMap<String,Object> params = new LinkedMultiValueMap<>();
params.add("file", new FileSystemResource(file));
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.IMAGE_JPEG);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, httpHeaders);
return restTemplate.exchange(UPLOAD_URL, HttpMethod.POST, requestEntity, String.class);
Exception:
org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.util.LinkedMultiValueMap] and content type [image/jpeg]
Upload works with Content-Type MediaType.MULTIPART_FORM_DATA but REST Service that I use only accepts image/jpg as HTTP Content-Type.
Thanks.
Your remote service accept image/jpg so you should stream byte instead of multi-part:
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "image/jpeg");
Resource res = new InputStreamResource(file.getInputStream());
HttpEntity<Resource> entity = new HttpEntity<>(res, headers);
template.exchange(UPLOAD_URL, HttpMethod.POST, entity , String.class);
The RestTemplate has ResourceHttpMessageConverter which streams your multi-part to the service for you.

Xamarin__HttpClient__HttpResponseMessage-Content --- Getting HTML instead of JSON

HttpClient myClient = new HttpClient();
myClient.BaseAddress = new Uri(URL);
Base address already specified on client it's URL.
var encodedObject = JsonConvert.SerializeObject(Obj);
myClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await myClient.PostAsync("test.php/yourAPI",new StringContent(encodedObject, System.Text.Encoding.UTF8, "application/json"));
if (response.IsSuccessStatusCode)
{
var responseContent = response.ToString();
var responsebody = response.Content.ToString();
Stream receiveStream = response.GetResponseStream();
string responseBodyAsText = response.Content.ReadAsStringAsync().Result;
}
Could be a content negotiation issue. Try clearing the Accept header before adding the json media type
myClient.DefaultRequestHeaders.Accept.Clear();
myClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//...other code removed for brevity.
this code sets the Accept header to "application/json", which tells the server to send data in JSON format.
Reference source: Calling a Web API From a .NET Client in ASP.NET Web API 2
the Method PostAsync has as first argument the complete URI of The API. Therefore, it should be like follow :
HttpResponseMessage response = await myClient.PostAsync("http://bla-bla-bla/test.php/test",new StringContent(encodedObject, System.Text.Encoding.UTF8, "application/json"));
And there is no need to define the BaseAddress.

IdentityServer3 Response status code does not indicate success: 400 (Bad Request)

I always get Bad Request 400 from IdentityServer3. I am trying for 3 days now but no luck :( Anyone could please tell me what am I doing wrong?
I am trying to access IdentityServer3 hosted by another vendor that I have no control. The vendor has asked us to implement Implement OAuth2 authentication with Bearer token. The vendor provided us with the Client ID, Client Secret and the URL to be used is http://www.xxxxxx.com/identity/connect/token
The vendor told us to use to request bearer token and use it in the request headers Authorization: Bearer
I can successfully obtain the bearer token from vendor. But when I call the
GET /api/profiles/myemailaddress#gmail.com I get Bad Request 400
Here is what I have done:
TokenClient client = new TokenClient("http://www.xxxxxx.com/identity/connect/token", "myclientid", "myclientsecret", AuthenticationStyle.PostValues);
var response = await client.RequestResourceOwnerPasswordAsync("myemailaddress#gmail.com", "mypassword", "profile"); // successfully gives me the token
i got the access token, now i want to use the token to request user profile:
var clienthttp = new HttpClient();
clienthttp.BaseAddress = new Uri("http://www.xxxxxx.com");
clienthttp.SetBearerToken(response.AccessToken);
var json = await clienthttp.GetStringAsync("http://www.xxxxxx.com/api/profiles/myemailaddress#gmail.com"); // error Bad Request 400
Additional Info:
"scopes_supported":["profile","offline_access"],
"claims_supported":[]
Thank you.
The vendor was expecting additional value in the header. Since my request was missing that additional value, they returned Bad Request. I had to modify my code to find the exact reason of bad request.
Here is the updated code, might be useful for someone:
var client = new HttpClient();
client.BaseAddress = new Uri("http://www.xxxxx.com");
client.SetBearerToken(response.AccessToken);
var callApiResponse = client.GetAsync("api/profiles/myemailaddress#gmail.com").Result;
string tokenresponse = callApiResponse.StatusCode.ToString();
string clientresult = callApiResponse.Content.ReadAsStringAsync().Result;
tokenresponse: "Bad Request 400"
clientresult: "Missing CompanyID in the header"
Then I knew that they also expect companyid in the header so I added it. then all was good.
client.DefaultRequestHeaders.Add("CompID", "xxxxxx");
I had a similar error (Response status code does not indicate success: 400 (Bad Request)) for different resource not identity server. i manage to resolve that using FormUrlEncodedContent
Refer below code
using (HttpClient client = new HttpClient())
{
string baseUrl = "https://*******.com/****"
Dictionary<string, string> jsonValues = new Dictionary<string, string>();
jsonValues.Add("username", "******");
jsonValues.Add("password", "******");
var contenta = new FormUrlEncodedContent(jsonValues);
var response = await client.PostAsync(baseUrl, contenta);
using (HttpContent content = response.Content)
{
string data = await content.ReadAsStringAsync();
if (data != null)
{
Console.WriteLine(data);
}
}
}

Resources