I am trying to send HttpClient PostAsync() request to company's internal sharepoint site but its returning response with forbidden error. I have all necessary access permission for site to load and have also passed required headers to the HttpClient object.
Here is code snippet.
HttpClient client = new System.Net.Http.HttpClient (new HttpClientHandler { UseDefaultCredentials = true });
client.BaseAddress = new Uri (string.Format (API_URL, p_siteNumber));
client.DefaultRequestHeaders.Accept.Add (new MediaTypeWithQualityHeaderValue (#"application/atom+xml"));
client.DefaultRequestHeaders.TryAddWithoutValidation ("Accept-Encoding", "gzip, deflate");
client.DefaultRequestHeaders.TryAddWithoutValidation ("Accept-Language", "en-US, en;q=0.8, hi;q=0.6");
client.DefaultRequestHeaders.TryAddWithoutValidation ("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0");
client.DefaultRequestHeaders.TryAddWithoutValidation ("Accept-Charset", "ISO-8859-1");
HttpResponseMessage httpResponse = await client.PostAsync (urlHttpPost, new StringContent (string.Empty));
string response = await httpResponse.Content.ReadAsStringAsync ();
Can anyone help me with this?
Thanks in advance.
I ran into the same problem I wanted to send the file and some string contents with it.
so below code helped me!!
using (var client = new HttpClient())
{
//client.DefaultRequestHeaders.Add("User-Agent", "CBS Brightcove API Service");
string authorization = GenerateBase64();
client.DefaultRequestHeaders.Add("Authorization", authorization);
using (var content = new MultipartFormDataContent())
{
string fileName = Path.GetFileName(textBox1.Text);
//Content-Disposition: form-data; name="json"
var stringContent = new StringContent(InstancePropertyObject);
stringContent.Headers.Remove("Content-Type");
stringContent.Headers.Add("Content-Type", "application/json");
stringContent.Headers.Add("Content-Disposition", "form-data; name=\"instance\"");
content.Add(stringContent, "instance");
var fileContent = new ByteArrayContent(filecontent);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
content.Add(fileContent);
var result = client.PostAsync(targetURL, content).Result;
}
}
Related
I am trying post api through HTTP client in C#, For authorization ,we send Bearer token.
But it is not getting inserted in the client side. It throws an error.
My code here:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
string result = "";
using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.BaseAddress = new Uri(baseURL);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("Cookie", "ebpPermHash=-396055074);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + authtoken);
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
client.DefaultRequestHeaders.Add("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache")
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
HttpResponseMessage response = client.PostAsJsonAsync("/v2/bb/sa", payModel).Result;
var responseString = response.Content.ReadAsStringAsync();
result = responseString.Result;
dynamic data = JObject.Parse(result);
string throwresult = Convert.ToString(data);
result = data.authToken;
logErr.ControlLog(throwresult);
}
return result;
But I am getting error like:
exceptionType": "com.ebpsource.exception.AuthenticationFailedException",
"name": "AUTHENTICATION_REQUIRED",
"message": "Authentication is required to call 'Resource.execute'",
"address": "/service/Resource.execute",
"httpRequestBody": {
"header": {
"config": {
"action": "insert",
"resourceName": "sa"
}
Thanks in advance.
I suggest you check your backend with Postman first, to verify if it is a backend issue or a client issue
you have a bug, a wrong syntax to add a token. And plus to many headers. Try this
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
client.BaseAddress = new Uri(baseAddress);
var jsonData = JsonConvert.SerializeObject(payModel);
var contentData = new StringContent(jsonData, Encoding.UTF8, "application/json");
var response = client.PostAsync("/v2/bb/sa", contentData).Result;
if (response.IsSuccessStatusCode)
{
var stringData = response.Content.ReadAsStringAsync().Result;
var result = JsonConvert.DeserializeObject<object>(stringData);
}
}
UPDATE
if you need to add cookies you can do it this way
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler))
{
....
cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value"));
.....
}
Using RESTSharp, I am able to login:
RestClient client = new RestClient(Constants.APIURL + "method/login");
CookieContainer cookieJar = new CookieContainer();
RestRequest request = new RestRequest(Method.POST);
client.CookieContainer = cookieJar;
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddJsonBody(new
{
usr = username,
pwd = password
});
var response = client.Execute(request);
var cookie = HttpContext.Current.Server.UrlDecode(response.Headers.ToList().Find(x => x.Name == "Set-Cookie").Value.ToString());
I am then storing the cookies and sending to another API call, also through RESTSharp.
RestClient client = new RestClient(Constants.APIURL);
RestRequest request = new RestRequest("resource/Asset", Method.GET);
request.AddCookie("Cookie", HttpContext.Current.Server.UrlEncode(cookie));
But it keeps returning 403 forbidden. I tried on POSTMan, it works absolutely fine.
Any help? Is it that I am sending the cookies wrongly? I tried sending the cookies in a HttpWebRequest and it is working absolutely fine.
I also tried copy pasting a code generated from Postman where cookie was passed in a header but it didn't work. I tried sending cookie as below and it worked
client.AddDefaultHeader("Cookie", cookie);
235 / 5.000
Resultados de traducción
For RestSharp v107 and >
You can use CookieContainer and in it store all received Cookies.
then pass the CookieContainer to RestClientOptions and use it as a parameter when instantiating var client1 = new RestClient(options);
CookieContainer cookieJar = new CookieContainer();
cookieJar.Add(response.Cookies);
var options1 = new RestClientOptions(UL.moodle_host + "login/index.php?")
{
ThrowOnAnyError = true,
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0",
FollowRedirects = true,
CookieContainer = cookieJar
};
// new request TRY loging
var client1 = new RestClient(options1);
I have used postman to send a post request by attaching a file in the request body. Below is the postman request sample. I got success response with the response content.
var client = new RestClient("https://***********");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Connection", "keep-alive");
request.AddHeader("Content-Length", "757");
request.AddHeader("Accept-Encoding", "gzip, deflate");
request.AddHeader("Host", "**********");
request.AddHeader("Postman-Token", "********");
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("Accept", "*/*");
request.AddHeader("User-Agent", "PostmanRuntime/7.18.0");
request.AddHeader("Authorization", "Bearer XX");
request.AddHeader("Content-Type", "multipart/form-data");
request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundaryabc");
request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundaryabc", "------WebKitFormBoundaryabc\r\nContent-Disposition: form-data; **name=\"\"**; filename=\"sample.csv\"\r\nContent-Type: text/csv\r\n\r\n\r\n------WebKitFormBoundaryabc--", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Actual expected response from api call using postman is:
IssussessStatusCode: true{ ResponseData { file Name : "sample", readable :true} }
I have used C# httpClient method as below to do the same call
using (var _httpClient = new HttpClient())
{
using (var stream = File.OpenRead(path))
{
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Add("Accept", "*/*");
_httpClient.DefaultRequestHeaders.Add("cache-control", "no-cache");
_httpClient.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
_httpClient.DefaultRequestHeaders.Add("Host", "*********");
_httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer XX");
_httpClient.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("multipart/form-data")); // ACCEPT header
var content = new MultipartFormDataContent();
var file_content = new ByteArrayContent(new StreamContent(stream).ReadAsByteArrayAsync().Result);
file_content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
file_content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = "sample.csv",
**Name = " ", // Is this correct. In postman request it is **name=\"\"****
};
content.Add(file_content);
_httpClient.BaseAddress = new Uri("**************");
var response = await _httpClient.PostAsync("****url", content);
if (response.IsSuccessStatusCOde)
{
string responseBody = await response.Content.ReadAsStringAsync();
}
}
}
I am getting tresponse this way
Result: "\u001f�\b\0\0\0\0\0\u0004\0�\a`\u001cI�%&/m�{\u007fJ�J��t�\b�`\u0013$ؐ#\u0010������\u001diG#)�*��eVe]f\u0016#�흼��{���{���;�N'���?\\fd\u0001l��J�ɞ!���\u001f?~|\u001f?\"~�G�z:͛�G�Y�䣏��\u001e�⏦�,�������G\vj�]�_\u001f=+�<����/��������xR,�����4+�<�]����i�q��̳&O���,�\u0015��y�/۴�/�����r�������G��͊�pX������\a�\u001ae_�\0\0\0"
Here I get some decoded values when I execute `response.Content.ReadAsStringAsync();`
Can someone help me on what needs to be done here?
Ok , i understand your problem. The api is returning response in a compressed format. You need to Deflate/Gzip it. I have faced similar problems earlier. Try my solution.
You need to make use of the HttpClientHandler() class like this.
var httpClientHandler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
};
_httpClient = new HttpClient(httpClientHandler);
When the httpClient gets instantiated, you need to pass in the handler in the first place.
I am trying to update a SharePoint 2013 list title using the REST api and HttpClient. I have the following code but the StatusCode is returning BadRequest.
private async void UpdateTitle()
{
string webUrl = http://server;
Uri uri = new Uri(webUrl + "/_api/web/lists/GetByTitle('Old')");
//start replacement
HttpClientHandler httpClientHandler = new HttpClientHandler();
httpClientHandler.UseDefaultCredentials = true;
HttpClient client = new HttpClient(httpClientHandler);
client.DefaultRequestHeaders.Add("ContentType", "application/json;odata=verbose");
string digest = await GetFormDigest("http://devsp13.dev.local/_api/contextinfo");
client.DefaultRequestHeaders.Add("X-RequestDigest", digest);
client.DefaultRequestHeaders.Add("X-HTTP-Method", "Merge");
client.DefaultRequestHeaders.Add("IF-MATCH", "*");
HttpContent content = new StringContent("{ '__metadata': { 'type': 'SP.List' }, 'Title': 'NewTitle' }");
HttpResponseMessage response = await client.PostAsync(uri, content);
response.EnsureSuccessStatusCode();}
I'm guessing I've missed something in forming the HttpClient but I'm struggling to see what. Any help is much appreciated.
Cheers,
Geoff
Try adding Accept to the HttpClient DefaultRequestHeaders and set the ContentType on the HttpContent Headers instead. This worked for me.
HttpClientHandler handler = new HttpClientHandler();
handler.UseDefaultCredentials = true;
HttpClient client = new HttpClient(handler);
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("X-RequestDigest", GetFormDigest());
client.DefaultRequestHeaders.Add("X-HTTP-Method", "MERGE");
client.DefaultRequestHeaders.Add("IF-MATCH", "*");
HttpContent content = new StringContent(metadataString);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("odata", "verbose"));
HttpResponseMessage response = await client.PostAsync(uri, content);
response.EnsureSuccessStatusCode();
This is driving me nuts, I am setting the ContentType header everywhere I can and can't seem to make it stop sending text/plain.
Watching the data in Fiddler, the request is always requesting:
POST http:/domain.com HTTP/1.1
Content-Type: text/plain; charset=utf-8
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Post, "http://domain.com");
request.Content = new StringContent(Serialize(obj), Encoding.UTF8, "text/xml");
request.Content.Headers.Clear();
request.Content.Headers.ContentType = new MediaTypeHeaderValue("text/xml");
request.Headers.Clear();
request.Headers.Add("Content-Type","text/xml");
var response = await httpClient.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
It looks like you tried to hard :) This should just work.
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Post, "http://domain.com");
request.Content = new StringContent(Serialize(obj), Encoding.UTF8, "text/xml");
var response = await httpClient.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
Try settings the default request headers:
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
Use "application/xml" instead of "text/xml"