How to PATCH data using System.Net.Http - c#

I have uploaded a file to SharePoint and found out what id it has. Now I need to update some of the other columns on that listitem. The problem is that System.Net.Http.HttpMethod.Patch doesn't exist.
public static async Task<string> UpdateFileData()
{
var (authResult, message) = await Authentication.AquireTokenAsync();
string updateurl = MainPage.rooturl + "lists/edd49389-7edb-41db-80bd-c8493234eafa/items/" + fileID + "/";
var httpClient = new HttpClient();
HttpResponseMessage response;
try
{
var root = new
{
fields = new Dictionary<string, string>
{
{ "IBX", App.IBX }, //column to update
{ "Year", App.Year}, //column to update
{ "Month", App.Month} //column to update
}
};
var s = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat };
var content = JsonConvert.SerializeObject(root, s);
var request = new HttpRequestMessage(HttpMethod.Put, updateurl);
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
request.Content = new StringContent(content, Encoding.UTF8, "application/json");
response = await httpClient.SendAsync(request);
var responseString = await response.Content.ReadAsStringAsync();
return responseString;
}
catch (Exception ex)
{
return ex.ToString();
}
}

Modify the code as below.
public static async Task<string> UpdateFileData()
{
var (authResult, message) = await Authentication.AquireTokenAsync();
string updateurl = MainPage.rooturl + "lists/edd49389-7edb-41db-80bd-c8493234eafa/items/" + fileID + "/";
var httpClient = new HttpClient();
HttpResponseMessage response;
try
{
var root = new
{
fields = new Dictionary<string, string>
{
{ "IBX", App.IBX }, //column to update
{ "Year", App.Year}, //column to update
{ "Month", App.Month} //column to update
}
};
var s = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat };
var content = JsonConvert.SerializeObject(root, s);
var request = new HttpRequestMessage(new HttpMethod("PATCH"), updateurl);
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
request.Content = new StringContent(content, System.Text.Encoding.UTF8, "application/json;odata=verbose");
response = await httpClient.SendAsync(request);
var responseString = await response.Content.ReadAsStringAsync();
return responseString;
}
catch (Exception ex)
{
return ex.ToString();
}
}
Or we can also use REST API to update list item by ID.
Refer to: SharePoint 2013 REST Services using C# and the HttpClient

It dependents whether .NET Core or .NET Framework is utilized, in case of `.NET Core HttpClient.PatchAsync Method could be utilized.
In case of .NET Framework ListItem could be updated like this:
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.BaseAddress = new Uri("https://graph.microsoft.com");
var listItemPayload = new Dictionary<string, object>
{
{"Color", "Fuchsia"},
{"Quantity", 934}
};
var requestContent = new StringContent(JsonConvert.SerializeObject(listItemPayload));
requestContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = await client.PatchAsync(new Uri($"https://graph.microsoft.com/v1.0/sites/{siteId}/lists/{listId}/items/{itemId}/fields"), requestContent);
var data = response.Content.ReadAsStringAsync().Result.ToString();
}
where PatchAsync is the extension method for HttpClient class:
public static class HttpClientExtensions
{
public static async Task<HttpResponseMessage> PatchAsync(this HttpClient client, Uri requestUri, HttpContent iContent)
{
var method = new HttpMethod("PATCH");
var request = new HttpRequestMessage(method, requestUri)
{
Content = iContent
};
HttpResponseMessage response = new HttpResponseMessage();
try
{
response = await client.SendAsync(request);
}
catch (TaskCanceledException e)
{
Debug.WriteLine("ERROR: " + e.ToString());
}
return response;
}
}
All the credits for extension method go to the author of this answer

Can't you just use the HttpMethod class constructor?
new HttpMethod("PATCH");
Source: https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpmethod.-ctor?view=netframework-4.7.2#System_Net_Http_HttpMethod__ctor_System_String_

Related

Postman form-data: How to program it inside a HttpRequestMessage?

I am doing a request through postman to a specific url but I set the form-data type in order to get data to the site like this:
Now I want to program this request inside C# but everything I tried so far is returning a 400 Bad Request response. This is what I tried:
public async Task<CheckAccessTokenModel> CheckAccessTokenAsync(string accessToken)
{
string uriString = "someurl";
var uri = new Uri(uriString);
try
{
using(var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = uri
};
var ClientId = ConfigurationAccessor.Configuration["WebCredentials:ClientId"];
var Secret = ConfigurationAccessor.Configuration["WebCredentials:Secret"];
var authString = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{ClientId}:{Secret}"));
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authString);
MultipartFormDataContent content = new MultipartFormDataContent();
content.Add(new StringContent("token"), accessToken);
request.Content = content;
var response = await httpClient.SendAsync(request);
var checkTokenResponseData = await response.Content.ReadAsStringAsync();
//return new CheckAccessTokenModel { Active = true, Exp = 1647431224233 };
return JsonConvert.DeserializeObject<CheckAccessTokenModel>(checkTokenResponseData);
}
}
catch
{
return null;
}
}
I am doing it with the MultipartFormDataContent Object as suggested by many others here but it still won't work.
What can be the problem here?
EDIT: Wrong picture replaced
You can simply
request.Content = new StringContent($"token={accessToken}");
With form data I think it's something like this:
var data = new Dictionary<string, string>
{
{"token", acccessToken}
};
using var content = new FormUrlEncodedContent(data);
request.Content = content;

How to send a post request in dotnet with a list of request headers

public static async Task<HttpResponseMessage> Post(string endPoint, string data){
HttpContent c = new StringContent(data, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(VodapayBaseUrl + endPoint),
Content = c,
};
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage result = await client.SendAsync(request).ConfigureAwait(false); // The code fails here
if (result.IsSuccessStatusCode)
{
Console.WriteLine("got here");
return result;
}
else
{
Console.WriteLine("failled");
return result;
}
}
// return result;
}
Here is an updated version:
public static async Task Post()
{
using (var httpClient = new HttpClient())
{
var requestString = "{\"authCode\": \"0000000001Nk1EEhZ3pZ73z700271891\" }";
httpClient.BaseAddress = new Uri("https://bounties-backend-mini-program.herokuapp.com");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var request = new HttpRequestMessage(HttpMethod.Post, $"/api/userInfo");
request.Content = new StringContent(requestString, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine(JsonConvert.SerializeObject(response.Headers.ToList()));
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Successful");
Console.WriteLine(responseContent);
}
else
{
Console.WriteLine("Not successful");
}
}
}
class Program
{
private static void Main(string[] args)
{
Post().Wait();
Console.WriteLine();
}
}
}
Can someone please help with this I am new to c# and relatively new to coding. I am trying to send a request using httpclient I need to send data in a json format I also need to send a list of headers. How can I do this and also return json data at the end your help will be appreciated.I am getting an error when i run this:
Your code isn't far off, here's an example that I had in one of my projects ...
using (var httpClient = new HttpClient())
{
var requestString = "{\"authCode\": \"0000000001Nk1EEhZ3pZ73z700271891\" }";
// Setup the HttpClient and make the call and get the relevant data.
httpClient.BaseAddress = new Uri("https://bounties-backend-mini-program.herokuapp.com");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var request = new HttpRequestMessage(HttpMethod.Post, $"/api/userInfo");
request.Content = new StringContent(requestString, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(request);
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine(JsonConvert.SerializeObject(response.Headers.ToList()));
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Successful");
Console.WriteLine(responseContent);
}
else
{
Console.WriteLine("Not successful");
}
}
... obviously, it has varying degrees of thought for the scenario at hand but just adapt it as need be.

How to POST a JsonString and a HttpPostedFileBase picture to a Web Service?

The Json string has this structure:
{"CODIGO_AGENCIA":"HN001001","CODIGO_USUARIO":"some user","CODIGO_CATEGORIA":1}
This is the parameter asked by the WS:
public async Task SubirImagenCategoria(string JsonString, HttpPostedFileBase Archivo)
//This is what I got so far, the web service returns error that the json string is empty, I am completely lost on how to proceed.
public static async Task<CustomJsonResult> SubirImagenCategoría(int CodigoCategoria, HttpPostedFileBase Archivo)
{
usuario = UtilClass.GetUsuarioSesion();
var modelo = new SUBIR_IMAGEN_CAT();
modelo.CODIGO_AGENCIA = usuario.CodigoAgencia;
modelo.CODIGO_USUARIO = usuario.Nombre;
modelo.CODIGO_CATEGORIA = 1;
CustomJsonResult result = new CustomJsonResult();
try
{
var JsonString = JsonConvert.SerializeObject(modelo);
var formContent = new MultipartFormDataContent("form-data");
StringContent jsonPart = new StringContent(JsonString.ToString());
jsonPart.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
jsonPart.Headers.ContentType = new MediaTypeHeaderValue("application/json");
formContent.Add(jsonPart);
/* byte[] Bytes = new byte[Archivo.InputStream.Length + 1];
Archivo.InputStream.Read(Bytes, 0, Bytes.Length);
var fileContent = new ByteArrayContent(Bytes);
fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") { FileName = Archivo.FileName };
formContent.Add(fileContent);*/
StreamContent filePart = new StreamContent(Archivo.InputStream);
filePart.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
filePart.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
filePart.Headers.ContentDisposition.FileName = Archivo.FileName;
formContent.Add(filePart);
var test = formContent;
/*HttpContent jsonParam = new StringContent(JsonString);
HttpContent fileStream = new StreamContent(Archivo.InputStream);
formData.Add(jsonParam, "JsonString", "JsonString");
formData.Add(fileStream, "Archivo", "Archivo");*/
/*var values = new Dictionary<string, string>
{
{ "JsonString", ("{\"CODIGO_AGENCIA\":"+usuario.CodigoAgencia+",\"CODIGO_USUARIO\":\""+usuario.Nombre+"\" ,\"CODIGO_CATEGORIA\":\""+CodigoCategoria+"\"}") },
};
HttpContent myBody = new FormUrlEncodedContent(values);*/
var formData = new MultipartFormDataContent();
String url = DataEntityLayer.Database.Environment.getFinalUrl(Util.UtilWS.subirImagenesCategorias);
var myHttpClient = new HttpClient();
var response = await myHttpClient.PostAsync(url, formContent);
string stringContent = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<CustomJsonResult>(stringContent);
}
catch (Exception ex)
{
result.Error = ex.Message;
}
return result;
}
This is how I tested the WS from postman
After many attempts and almost having a mental & emotional breakdown, it finally worked.
Example 3 from this link worked for me.
public static UsuarioSesion usuario = new UsuarioSesion();
public static async Task<CustomJsonResult> SubirImagenCategoría(int CodigoCategoria, HttpPostedFileBase Archivo)
{
usuario = UtilClass.GetUsuarioSesion();
var modelo = new SUBIR_IMAGEN_CAT();
modelo.CODIGO_AGENCIA = usuario.CodigoAgencia;
modelo.CODIGO_USUARIO = usuario.Nombre;
modelo.CODIGO_CATEGORIA = CodigoCategoria;
CustomJsonResult result = new CustomJsonResult();
try
{
var JsonString = JsonConvert.SerializeObject(modelo);
var formContent = new MultipartFormDataContent();
HttpContent JsonParam = new StringContent(JsonString);
formContent.Add(JsonParam, "JsonString");
var fileContent = new StreamContent(Archivo.InputStream);
fileContent.Headers.Add("Content-Type", "application/octet-stream");
fileContent.Headers.Add("Content-Disposition", "form-data; name=\"Archivo\"; filename=\"" + Archivo.FileName.ToString() + "\"");
formContent.Add(fileContent, "file", Archivo.FileName.ToString());
String url = DataEntityLayer.Database.Environment.getFinalUrl(Util.UtilWS.subirImagenesCategorias);
var myHttpClient = new HttpClient();
var response = await myHttpClient.PostAsync(url, formContent);
string stringContent = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<CustomJsonResult>(stringContent);
}
catch (Exception ex)
{
result.Error = ex.Message;
}
return result;
}

How to make POST request on BamBhooHr Api in C#

I want to add Employee on BamBhooHr using Bambhoohr REST API in MVC C#.
I have tried 2 content types to post as shown in the code but not succeed.
1==>
public async System.Threading.Tasks.Task<JsonResult> AddEmployee(string fn,string ln)
{
var _resultModel = new BBHEmployee();
var _bambhoohrApi = "https://epicsoftsandbox.bamboohr.com/api/gateway.php/epicsoftsandbox/v1/employees";
var _apiKey = "b2aef724a48603468bfe85dce9e417ac8cf15fdf";
var _url = $"{_bambhoohrApi}";
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(_apiKey + ":x");
var base64encodedData = System.Convert.ToBase64String(plainTextBytes);
using (var _client = new HttpClient())
{
var _postData = new Dictionary<string, string>
{
{ "firstName", fn },
{ "lastName", ln }
};
_client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", base64encodedData);
var _response = await _client.PostAsync(_url, new FormUrlEncodedContent(_postData));
var _content = await _response.Content.ReadAsStringAsync();
_resultModel = JsonConvert.DeserializeObject<BBHEmployee>(_content);
}
return Json(_resultModel, JsonRequestBehavior.AllowGet);
}
2==>
public async System.Threading.Tasks.Task<JsonResult> AddEmployee(string fn,string ln)
{
var _resultModel = new BBHEmployee();
var _bambhoohrApi = "https://epicsoftsandbox.bamboohr.com/api/gateway.php/epicsoftsandbox/v1/employees";
var _apiKey = "b2aef724a48603468bfe85dce9e417ac8cf15fdf";
var _url = $"{_bambhoohrApi}";
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(_apiKey + ":x");
var base64encodedData = System.Convert.ToBase64String(plainTextBytes);
using (var _client = new HttpClient())
{
_client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", base64encodedData);
_client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var jsonString = "{\"firstName\":\"" + fn + "\",\"lastName\":\"" + ln + "\"}";
StringContent _contt = new StringContent(jsonString, Encoding.UTF8, "application/json");
var _response = await _client.PostAsync(_url, _contt);
var _content = await _response.Content.ReadAsStringAsync();
_resultModel = JsonConvert.DeserializeObject<BBHEmployee>(_content);
}
return Json(_resultModel, JsonRequestBehavior.AllowGet);
}
with both ways, it returns StatusCode 400(BadRequeest)
in that case, this BambhooHr API endpoint requires XML data to post,
so I use this and it's working fine.
var xmlString = "<employee><field id = \"firstName\">"+fn+"</field><field id = \"lastName\">"+ln+"</field></employee>";
var _contt = new StringContent(xmlString,Encoding.UTF8, "text/xml");
var _response = await _client.PostAsync(_url, _contt);

How to Async httpclient with Patch Method

I am trying to consume [this API] (https://learn.microsoft.com/en-us/rest/api/vsts/release/approvals/update). Below is my code, but i am getting 400 bad request.
HttpContent z = new StringContent("{\"status\": \"approved\",\"comments\": \"" + Request.QueryString["comment"].ToString() + "\"}", Encoding.UTF8, "application/json");
public static async Task PatchAsync(Uri requestUri, HttpContent content)
{
try
{
using (HttpClient client = new HttpClient())
{
var method = new HttpMethod("PATCH");
var request = new HttpRequestMessage(method, requestUri)
{
Content = content
};
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", "XXXXXXXXX"))));
//using (HttpResponseMessage response = await client.PostAsync(requestUri, content))
using (HttpResponseMessage response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
respApproval = responseBody;
}
}
}
catch (Exception ex)
{
respApproval = ex.ToString();
}
}
Since you only provide part of the code, I posted my code (which can update approvals successfully) below for your refernce:
public static async void ApproveRelease()
{
try
{
var username = "alternate auth or PAT";
var password = "password";
string accountName = "https://account.visualstudio.com";
string projectName = "projectname";
int approvalid = id;
var approveReleaseUri = "https://accountname.vsrm.visualstudio.com/projectname/_apis/release/approvals/approvlID?api-version=4.1-preview.3";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", username, password))));
var method = new HttpMethod("PATCH");
string approvveReleaseMetaData = "{\"status\":\"approved\", \"comments\":\"Good to go\"}";
var request = new HttpRequestMessage(method, string.Format(approveReleaseUri, accountName, projectName, approvalid, apiVersion))
{
Content = new StringContent(approvveReleaseMetaData, Encoding.UTF8, "application/json")
};
using (HttpResponseMessage response = client.SendAsync(request).Result)
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
By referring the blog Using ReleaseManagement REST API’s.
Note: you can only update a release approval which status is pending. If you try to update a release approval which approval status is approved or rejected, you will also get the 400 bad request response.

Categories