C# HttpClient PostAsync with JSON parameter for VSO git API - c#

I am trying to understand the VSO git API. I have made Get requests succesfully like so:
using (var response = client.GetAsync(
uri).Result)
{
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
ResponseInfo.Text = JsonHelper.FormatJson(responseBody);
}
I do this after setting client.DefaultRequestHeaders for Basic Authentication and Mediatype to application/json.
For post requests, the VSO Documentation shows this:
I understand that the parameters are JSON. However, I'm not sure how to pass that into the post request in C#. I have tried the following:
string content = #"{
""refUpdates"": [
{
""name"": ""refs/heads/master"",
""oldObjectId"": ""*old object id*""
}
],
""commits"": [
{
""comment"": ""Test commit"",
""changes"": [
{
""changeType"": ""edit"",
""item"": {
""path"": ""/foo.txt""
},
""newContent"": {
""content"": ""test"",
""contentType"": ""rawtext""
}
}
]
}
]
}";
var stringToJson= new JavaScriptSerializer();
var JSONoutput = stringToJson.Deserialize<object>(content);
StringContent stringContent = new StringContent(JSONoutput.ToString(), Encoding.UTF8, "application/json");
and then I pass that in to
using (var response = client.PostAsync(uri, stringContent).Result)
{
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
I get a 400 Bad Request error. Am I passing in my parameters correctly? Essentially I am taking the string version of what the tutorial gave me, convert it to JSON, deserialize it, convert it to HTTPContent, and pass that into PostAsync. I can't think of another way to do it.
Thank you for your time!

Turns out I can just do
StringContent stringContent = new StringContent(content, Encoding.UTF8, "application/json");
The string version of the JSON object is enough for StringContent.

Related

Post request to Minimal API service with JSON body

I've got a minimal API service with a MapPost:
app.MapPost("/sendmessage", (RabbitMessage rm) => server.SendMessage(rm.exchange,
rm.routingkey, rm.message));
app.Run();
record RabbitMessage(string exchange, string routingkey, string message);
It works fine when sending a JSON with Postman:
{
"message": "msg",
"routingkey": "freestorage",
"exchange": "system"
}
But from a C# client:
var kv = new Dictionary<string, string> {
{ "exchange", "system" },
{ "routingkey", routingkey },
{ "message", message }
};
var content = new FormUrlEncodedContent(kv);
string contentType = "application/json";
if (Client.DefaultRequestHeaders.Accept.FirstOrDefault(hdr => hdr.MediaType == contentType) == default)
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType));
var response = await Client.PostAsync("sendmessage", content);
The response is UnsupportedMediaType. What is the proper way to send these values to minimal API? Or do I need to setup the API itself differently?
I don't think using FormUrlEncodedContent is the correct way as it is used for application/x-www-form-urlencoded MIME type.
Instead, you should pass the request body with StringContent and serialize the kv as content.
using System.Text;
using Newtonsoft.Json;
var stringContent = new StringContent(JsonConvert.SerializeObject(kv),
Encoding.UTF8,
"application/json");
var response = await Client.PostAsync("sendmessage", stringContent);

Send a JSON request to another web site from C# code behind in an ASP.NET MVC project

I'm working with ASP.NET MVC (backend being C#) and I'm trying to send a json that would look like this :
{
"store_id": "store3",
"api_token": "yesguy",
"checkout_id": "UniqueNumber",
"txn_total": "10.00",
"environment": "qa",
"action": "preload"
}
to another web site, suppose it's something like:
https://TestGate.paimon.com/chkt/request/request.php
Through some research I found this :
Send json to another server using asp.net core mvc c#
Looks good but I'm not working in core, my project is just normal ASP.NET MVC. I don't know how to use json functions to send it to a web site.
Here is what I tried (updated after inspired by Liad Dadon answer) :
public ActionResult Index(int idInsc)
{
INSC_Inscription insc = GetMainModelInfos(idinsc);
JsonModel jm = new JsonModel();
jm.store_id = "store2";
jm.api_token = "yesguy";
jm.checkout_id = "uniqueId";
jm.txn_total = "123.00";
jm.environment = "qa";
jm.action = "preload";
var jsonObject = JsonConvert.SerializeObject(jm);
var url = "https://gatewayt.whatever.com/chkt/request/request.php";
HttpClient client = new HttpClient();
var content = new StringContent(jsonObject, System.Text.Encoding.UTF8, "application/json");
System.Threading.Tasks.Task<HttpResponseMessage> res = client.PostAsync(url, content);
insc.response = res.Result; // This cause an exeption
return View(insc);
}
When ths Json is posted correctly, the other web site will answer me with is own Json :
{
"response" :
{
"success": "true",
"ticket": "Another_Long_And_Unique_Id_From_The_Other_Web_Site"
}
}
What I need to do is retreive this Json answer, once I have it, the rest is piece of cake.
Infos :
After the PostAsync function, var res contains this :
It looks like you might not be correctly handling an asynchronous task — the WaitingForActivation message you’re seeing, rather than being a response from our API, is in fact the status of your task.
The task is waiting to be activated and scheduled internally by the .NET Framework infrastructure.
It seems you might need to await⁽²⁾ the task to ensure it completes or access the response with await client.PostAsync(url, content);. for adding await you need to add async to controller⁽¹⁾ action.
public async Task<ActionResult> Index(int idInsc) //Change here [1]
{
INSC_Inscription insc = GetMainModelInfos(idinsc);
JsonModel jm = new JsonModel();
jm.store_id = "store2";
jm.api_token = "yesguy";
jm.checkout_id = "uniqueId";
jm.txn_total = "123.00";
jm.environment = "qa";
jm.action = "preload";
var jsonObject = JsonConvert.SerializeObject(jm);
var url = "https://gatewayt.whatever.com/chkt/request/request.php";
HttpClient client = new HttpClient();
var content = new StringContent(jsonObject, System.Text.Encoding.UTF8, "application/json");
System.Threading.Tasks.Task<HttpResponseMessage> res = await client.PostAsync(url, content); //Change here [2]
insc.response = res.Result; // This cause an exeption
return View(insc);
}
This is how I would post a JSON object to somewhere using Newtonsoft.Json package, HttpClient and StringContent classes:
using Newtonsoft.Json;
var object = new Model
{
//your properties
}
var jsonObject = JsonConvert.SerializeObject(object);
var url = "http://yoururl.com/endpoint"; //<- your url here
try
{
using HttpClient client = new();
var content = new StringContent(jsonObject , Encoding.UTF8,
"application/json");
var res = await client.PostAsync(url, content);
}
Please make sure your function is async and that you await the client.PostAsync fucntion.
If someone is wondering how I finally pulled it off (with other's help) here it is :
var url = "https://gatewayt.whatever.com/chkt/request/request.php";
HttpClient client = new HttpClient();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var content = new StringContent(jsonObject, System.Text.Encoding.UTF8, "application/json");
var res = await client.PostAsync(url, content);
var jsonRes = await res.Content.ReadAsStringAsync();
This line is important var jsonRes = await res.Content.ReadAsStringAsync(); the object jsonRes will be a string value, which is actually the response. The var res will only be the status of the response, not the actual response.

Add a member to Microsoft Teams using Graph API and delegated permissions

I am trying to simply add a member (who is already in the organization) to a specific Microsoft Team. The observerID is the id of the the member that I want to add and teamID is is the ID of the specific Team. I am using delegated permission with TeamMembers.ReadWrite.All enabled.
My code looks like this:
string json = $#"
{{
""#odata.type"": ""#microsoft.graph.aadUserConversationMember"",
""roles"": [""member""],
""user#odata.bind"": ""https://graph.microsoft.com/beta/users({observerID})""
}}";
var body = new StringContent(json, Encoding.UTF8, "application/json");
Console.WriteLine("Add observer");
return await protectedApiCallHelper.CallWebApiAsync(WebApiUrlTeams + teamID + "/members", accessToken, body);
public async Task<JObject> CallWebApiAsync(string webApiUrl, string accessToken, HttpContent content)
{
if (!string.IsNullOrEmpty(accessToken))
{
var defaultRequestHeaders = HttpClient.DefaultRequestHeaders;
if (defaultRequestHeaders.Accept == null || !defaultRequestHeaders.Accept.Any(m => m.MediaType == "application/json"))
{
HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
defaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
HttpResponseMessage response = await HttpClient.PostAsync(webApiUrl, content);
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync();
JObject result = JsonConvert.DeserializeObject(json) as JObject;
return result;
}
}
return null;
}
My problem is that the http call fails with the status code 400; 'Bad Request'. I have tried again and again to find any issues with my call but I can't seem to find the problem. When I Console.WriteLine the json I use for the body it looks like this:
{
"odata.type": "#microsoft.graph.aadUserConversationMember",
"roles": ["member"],
"user#odata.bind": "https://graph.microsoft.com/beta/users(d52c2663-1c41-401b-8015-1216f0e68960)"
}
And the url looks like: "https://graph.microsoft.com/beta/teams/a9f9ac33-fba5-4ce2-9515-8c498c70af85/members" and when I try the call through Postman it still returns a error code 400.
Does anyone have any insight on what might be wrong?
In fact, this error is very simple. Reporting 400 is usually a parameter error. Your json file is missing the special symbols # and ". I tested it locally and worked for me.

gandi api call from C# returns 400. Its Working Fine from Postman

I have create gandi api code for create domain and for that i have write below code, but it show me 400 bad request error
public async System.Threading.Tasks.Task<JsonResult> InsertDomain(DomainDetails domainDetails)
{
HttpResponseMessage response = new HttpResponseMessage();
try
{
var url = "https://api.gandi.net/v5/domain/domains";
using ( var client = new HttpClient() )
{
var json = new JavaScriptSerializer().Serialize(domainDetails);
HttpContent HttpContent = new StringContent(json, Encoding.UTF8, "application/json");
var MyHttpClient = new HttpClient();
MyHttpClient.DefaultRequestHeaders.Add("authorization", GANDI_API_Key);
response = await MyHttpClient.PostAsync(url, HttpContent);
}
}
catch ( Exception ex )
{
throw;
}
return Json(new { result = response }, JsonRequestBehavior.AllowGet);
}
but when i try to pass same data using postman then it's working fine below code is my postman data
Body
{
"fqdn":"dedasdom1906.com",
"owner":
{
"city":"Paris",
"given":"Alice",
"family":"Doe",
"zip":"75001",
"country":"FR",
"streetaddr":"5 rue neuve",
"phone":"+33.123456789",
"state":"FR-J",
"type":"0",
"email":"alice#example.org"
}
}
Header
authorization : Apikey
Content-Type : application/json
I havent worked with this endpoint, but you are missing the return type.
the next thing i would try is to paste json string directly in the StringContent.
please paste the correct string content(rename the variable)
if none of this help you, please give more details.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
For the https://api.gandi.net/v5/domain/domains endpoint, use HTTP GET (HttpClient.GetAsync) to retrieve a list of your domains. Use HTTP POST (HttpClient.PostAsync) to create a new domain.
If you're trying to POST JSON, I would use the PostAsJsonAsync method, example here:
static async Task<Uri> CreateProductAsync(Product product)
{
HttpResponseMessage response = await client.PostAsJsonAsync(
"api/products", product);
...
Also note your auth header needs to start with "apikey" though it looks like you have that working. Curl example:
curl -X GET \
https://api.gandi.net/v5/domain/domains \
-H 'authorization: Apikey your-api-key'
https://api.gandi.net/docs/domains/

How to pull a LFS file from gitlab repo using api

I am trying to use the gitlab api to get a file from my repo without success. Can you give me some pointers? When I run my below C# code, I get this response
{
“message”: “Access forbidden. Check your access level.”,
“documentation_url”: “https://gitlab.com/help”
}
I am positive that I am passing my correct credentials.
C# code follows:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/vnd.git-lfs+json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", <my_username>, <my_password>))));
string json = #"{
'operation': 'download',
'transfers': [ 'basic' ],
'ref': { 'name': 'refs/heads/master' },
'objects': [
{
'oid': '9669a62bbe8d8150c11d814509078b5db8f73c97ecfc94beb1dc6b22130adf7b',
'size': 4465559,
'authenticated': true
}
]
}";
var response = client.PostAsync("https://gitlab.com/<my_repo>/info/lfs/objects/batch", new StringContent(JsonConvert.SerializeObject(json), Encoding.UTF8, "application/json"));

Categories

Resources