Updating SharePoint 2013 List Title Using REST and HttpClient - c#

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();

Related

RestSharp to HttpClient

var client = new RestClient("http://10.0.0.244:8885/terminal/info");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("apikey", "adasdsadasd");
var body = #"{}";
request.AddParameter("application/json", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Could someone, please, help me write this code with HttpClient?
I try following code.
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://10.0.0.244:8885/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Clear();
HttpRequestMessage request = new HttpRequestMessage();
request.Method = HttpMethod.Post;
request.RequestUri = new Uri($"{client.BaseAddress}/terminal/info");
request.Headers.Add("apikey", "adasdsadasd");
var body = Newtonsoft.Json.JsonConvert.SerializeObject(new { });
request.Content = new StringContent(body, Encoding.UTF8, "application/json");//CONTENT-TYPE header
request.Content.Headers.Clear();
request.Content.Headers.ContentLength = 2;
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.SendAsync(request).GetAwaiter().GetResult();
var x = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}
But it response with Status Code 400 (ParseError)
You can accomplish what you are trying to do with much less code. Also this should be in an async method. Below is an example
internal async Task<string> GetResponse()
{
using var client = new HttpClient();
client.BaseAddress = new Uri("http://10.0.0.244:8885/");
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("apikey", "adasdsadasd");
var content = new StringContent("{}", Encoding.UTF8, "text/plain");
var response = await client.PostAsync("/terminal/info", content);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
return null;
}

HttpClient sending parameter null

I'm trying to send data to an api with HttpClient but parameter I'm sending keeps received as 0.
What am I doing wrong here? It's my first usage of HttpClient so it's quite possible I mixed things or made some rookie mistake.
Path is correct, I can get results from Postman.
Code I'm using is this;
static async Task GetActivityList()
{
string uri = "/api/ExtraNet/GetActivityList";
HttpClient client = new HttpClient();
int SalesPersonId = 553;
string token = my token value is here;
client.BaseAddress = new Uri("http://localhost:16513/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var postData = "{\"SalesPersonId=\":\""+SalesPersonId+"\"}";
var stringContent = new StringContent( "{\"SalesPersonId=\":\"" + SalesPersonId + "\"}", Encoding.UTF8, "application/json") ;
var content = new StringContent(postData, Encoding.UTF8, "application/json");
var response = await client.PostAsync("http://localhost:16513/api/ExtraNet/GetActivityList", stringContent);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
I managed to send the parameter this way
string uri = "/api/ExtraNet/GetActivityList";
HttpClient client = new HttpClient();
int SalesPersonId = 553;
string token = "";
client.BaseAddress = new Uri("http://localhost:16513/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var stringContent = new FormUrlEncodedContent(new[] {
new KeyValuePair<string,string>("SalesPersonId","553")
});
var response = await client.PostAsync(uri, stringContent);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
Sending the parameters as FormUrlEncodedContent did the trick.

Set Authorization/Content-Type headers when call HTTPClient.PostAsync

Where can I set headers to REST service call when using simple HTTPClient?
I do :
HttpClient client = new HttpClient();
var values = new Dictionary<string, string>
{
{"id", "111"},
{"amount", "22"}
};
var content = new FormUrlEncodedContent(values);
var uri = new Uri(#"https://some.ns.restlet.uri");
var response = await client.PostAsync(uri, content);
var responseString = await response.Content.ReadAsStringAsync();
UPD
Headers I want to add:
{
"Authorization": "NLAuth nlauth_account=5731597_SB1, nlauth_email=xxx#xx.com, nlauth_signature=Pswd1234567, nlauth_role=3",
"Content-Type": "application/json"
}
Should I do the following?
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", "NLAuth nlauth_account=5731597_SB1, nlauth_email=xxx#xx.com, nlauth_signature=Pswd1234567, nlauth_role=3","Content-Type":"application/json");
The way to add headers is as follows:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Your Oauth token");
Or if you want some custom header:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("HEADERNAME", "HEADERVALUE");
This answer has SO responses already, see below:
Adding headers when using httpClient.GetAsync
Setting Authorization Header of HttpClient
UPDATE
Seems you are adding two headerrs; authorization and content type.
string authValue = "NLAuth nlauth_account=5731597_SB1,nlauth_email=xxx#xx.com, nlauth_signature=Pswd1234567, nlauth_role=3";
string contentTypeValue = "application/json";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authValue);
client.DefaultRequestHeaders.Add("Content-Type", contentTypeValue);
I know this was asked a while ago, but Juan's solution didn't work for me.
(Also, pretty sure this question is duplicated here.)
The method that finally worked was to use HttpClient with HttpRequestMessage and HttpResponseMessage.
Also note that this is using Json.NET from Newtonsoft.
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http.Headers;
using Newtonsoft.Json;
namespace NetsuiteConnector
{
class Netsuite
{
public void RunHttpTest()
{
Task t = new Task(TryConnect);
t.Start();
Console.WriteLine("Connecting to NS...");
Console.ReadLine();
}
private static async void TryConnect()
{
// dummy payload
String jsonString = JsonConvert.SerializeObject(
new NewObj() {
Name = "aname",
Email = "someone#somewhere.com"
}
);
string auth = "NLAuth nlauth_account=123456,nlauth_email=youremail#somewhere.com,nlauth_signature=yourpassword,nlauth_role=3";
string url = "https://somerestleturl";
var uri = new Uri(#url);
HttpClient c = new HttpClient();
c.BaseAddress = uri;
c.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", auth);
c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, url);
req.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");
HttpResponseMessage httpResponseMessage = await c.SendAsync(req);
httpResponseMessage.EnsureSuccessStatusCode();
HttpContent httpContent = httpResponseMessage.Content;
string responseString = await httpContent.ReadAsStringAsync();
Console.WriteLine(responseString);
}
}
class NewObj
{
public string Name { get; set; }
public string Email { get; set; }
}
}
The other answers do not work if you are using an HttpClientFactory, and here's some reasons why you should. With an HttpClientFactory the HttpMessages are reused from a pool, so setting default headers should be reserved for headers that will be used in every request.
If you just want to add a content-type header you can use the alternate PostAsJsonAsync or PostAsXmlAsync.
var response = await _httpClient.PostAsJsonAsync("account/update", model);
Unfortunately I don't have a better solution for adding authorization headers than this.
_httpClient.DefaultRequestHeaders.Add(HttpRequestHeader.Authorization.ToString(), $"Bearer {bearer}");
On dotnet core 3.1 trying to run the top answer:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Content-Type", "application/x-msdownload");
threw an exception: System.InvalidOperationException: Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.
What worked for me was to instead set HttpContent.Headers -> HttpContentHeaders.ContentType property with a MediaTypeHeaderValue value:
HttpClient client = new HttpClient();
var content = new StreamContent(File.OpenRead(path));
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-msdownload");
var post = client.PostAsync(myUrl, content);
I prefer to cache the httpClient so I avoid setting headers which could affect other requests and use SendAsync
var postRequest = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
postRequest.Headers.Add("Content-Type", "application/x-msdownload");
var response = await httpClient.SendAsync(postRequest);
var content = await response.Content.ReadAsStringAsync();

How do I add the profile parameter to the content-type header in C#?

I'm trying to set the content-type of my HttpClient Post request, and use the profile parameter, but when I change the content type I get an exception thrown:
"The format of value 'application/json; profile={URL HERE}' is
invalid."
For reference, I found this Q&A: Zoopla Sandbox with cURL http header error
X509Certificate2 cert = new X509Certificate2("cert.pfx", "PASSWORD");
WebRequestHandler handler = new WebRequestHandler();
handler.ClientCertificates.Add(cert);
var client = new HttpClient(handler);
client.BaseAddress = new Uri("https://realtime-listings-api.webservices.zpg.co.uk");
var stringContent = new StringContent(propertyData, Encoding.UTF8, "application/json; profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.1/schemas/listing/list.json");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var response = await client.PostAsync("/sandbox/v1/listing/list", stringContent);
return _resultFactory.Create(true, await response.Content.ReadAsStringAsync());
If you create a HttpRequestMessage and use client.SendAsync(), you can add the parameters to request.Content.Headers.ContentType.Parameters
var client = new HttpClient();
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list"))
{
request.Content = new StringContent("propertyData", Encoding.UTF8, "application/json");
request.Content.Headers.ContentType.Parameters.Add(
new NameValueHeaderValue("profile", "http://realtime-listings.webservices.zpg.co.uk/docs/v1.1/schemas/listing/list.json")
);
var response = await client.SendAsync(request);
//Handle response..
}
You don't need to use HttpRequestMessage but you do need to add the profile value as a quoted string via the NameValueHeaderValue parameter:
var content = new StringContent(request.ToJson(), Encoding.UTF8);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("profile", "\"https://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/update.json\""))
httpClient.PostAsync("listing/update", content);
This will get round the FormatException. Otherwise you will run into this dotnet bug.

Trustpilot OAuth Restful API: Unable to PostAsync

I am trying to use the Trustpilot API, to post invitations to review products.
I have successfully gone through the authentication step as you can see in the code below, however I am unable to successfully post data to the Trustpilot Invitations API. The PostAsnyc method appears to be stuck with an WaitingForActivation status. I wonder if there is anything you can suggest to help.
Here is my code for this (the API credentials here aren't genuine!):
using (HttpClient httpClient = new HttpClient())
{
string trustPilotAccessTokenUrl = "https://api.trustpilot.com/v1/oauth/oauth-business-users-for-applications/accesstoken";
httpClient.BaseAddress = new Uri(trustPilotAccessTokenUrl);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var authString = "MyApiKey:MyApiSecret";
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Base64Encode(authString));
var stringPayload = "grant_type=password&username=MyUserEmail&password=MyPassword";
var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage httpResponseMessage = httpClient.PostAsync(trustPilotAccessTokenUrl, httpContent).Result;
var accessTokenResponseString = httpResponseMessage.Content.ReadAsStringAsync().Result;
var accessTokenResponseObject = JsonConvert.DeserializeObject<AccessTokenResponse>(accessTokenResponseString);
// Create invitation object
var invitation = new ReviewInvitation
{
ReferenceID = "inv001",
RecipientName = "Jon Doe",
RecipientEmail = "Jon.Doe#comp.com",
Locale = "en-US"
};
var jsonInvitation = JsonConvert.SerializeObject(invitation);
var client = new HttpClient();
client.DefaultRequestHeaders.Add("token", accessTokenResponseObject.AccessToken);
var invitationsUri = new Uri("https://invitations-api.trustpilot.com/v1/private/business-units/{MyBusinessID}/invitations");
// This here as a status of WaitingForActivation!
var a = client.PostAsync(invitationsUri, new StringContent(jsonInvitation)).ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode());
}
This is how I solved the issue:
// Serialize our concrete class into a JSON String
var jsonInvitation = JsonConvert.SerializeObject(invitationObject);
// Wrap our JSON inside a StringContent which then can be used by the HttpClient class
var stringContent = new StringContent(jsonInvitation);
// Get the access token
var token = GetAccessToken().AccessToken;
// Create a Uri
var postUri = new Uri("https://invitations-api.trustpilot.com/v1/private/business-units/{BusinessUnitID}/invitations");
// Set up the request
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, postUri);
request.Content = stringContent;
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
request.Content.Headers.Add("token", token);
// Set up the HttpClient
var httpClient = new HttpClient();
//httpClient.DefaultRequestHeaders.Accept.Clear();
//httpClient.BaseAddress = postUri;
//httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
//httpClient.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en-US"));
var task = httpClient.SendAsync(request);
task.Wait();
This question here on SO was helpful:
How do you set the Content-Type header for an HttpClient request?

Categories

Resources