Following on from the following question
WPF / C# Submit button to POST API
I now want to amend the POST BODY to include Username and Password Variable.
The below is what I am using at the moment
var OktaUserName = ADAccountName;
var OktaPassword = Password;
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://trial.okta.com/api/v1/authn");
request.Content = new StringContent("{\"username\":"+OktaUserName+",\"password\":"+OktaPassword+",\"options\": {\"multiOptionalFactorEnroll\": true,\"warnBeforePasswordExpired\": true}}", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
var responseContent = await response.Content.ReadAsStringAsync();
MessageBox.Show("Alert", json, "OK");
MessageBox.Show(responseContent, "Message");
I expect that the username and password is pulled from the stored variables and then added to OKTA as a new user, however with the above I get an error
ErrorCode E000003 Error Summary The Request Body was not well-formed
Any help will be greatly appreciated
Thank you #Fildor, your answers helped.
My modified request.Content is as follows
request.Content = new StringContent("{\"username\":\""+ADAccountNameStr+"\",\"password\":\""+PasswordStr+"\",\"options\": {\"multiOptionalFactorEnroll\": true,\"warnBeforePasswordExpired\": true}}", Encoding.UTF8, "application/json");
Related
Trying to consume a REST api using HttpClient. Im required to pass username and password through the body. Below is my code,Its however not posting the data values;
var data = new Dictionary<string, string>
{ {"username","username"},
{"password","password"}};
var jsonData = JsonConvert.SerializeObject(data);
HttpClient client2 = new HttpClient();
var requestContent2 = new StringContent(data.ToString(), Encoding.UTF8, "application/json");
client2.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", access_token);
HttpResponseMessage response2 = await client2.PostAsync(nitaauthapi, requestContent2);
HttpContent content2 = response2.Content;
string result2 = await content2.ReadAsStringAsync();
JObject jObject2 = JObject.Parse(result2);
string NONCE = jObject2["NONCE"].Value<string>();
Here, you correctly encode your data as JSON:
var jsonData = JsonConvert.SerializeObject(data);
Afterwards, you ignore your JSON-encoded data and instead send the string "System.Collections.Generic.Dictionary`2[System.String,System.String]" (= the output of data.ToString()) to your API endpoint:
var requestContent2 = new StringContent(data.ToString(), Encoding.UTF8, "application/json");
To fix this, use jsonData in your StringContent instead of data.ToString().
How to avoid such issues in the future: Pay attention to Visual Studio's hints. Visual Studio will highlight jsonData in a light grey color and add three dots underneath to inform you that something might be wrong with it:
Hovering over it will produce a tooltip telling you that the variable's value is unused.
I am attempting to POST some JSON data to an API to add accounts.
The instructions specify the ids parameter can be: a string (comma-separated), or array of integers
I realize I could put comma delimited ids into the query string however I would like to POST this data as JSON as I may have a large number of these.
Here is what I have tried:
public static HttpClient GetHttpClient()
{
var property = Properties.Settings.Default;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(property.apiUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("X-OrgSync-API-Key", property.apiKey);
return client;
}
HttpClient client = Api.GetHttpClient();
string json = "{\"ids\":[10545801,10731939]}";
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{client.BaseAddress}/classifications/{classification.id}/accounts/add", httpContent);
It runs "successfully" but nothing actually gets set on the API server side.
Any ideas as to what I might be doing wrong here?
Additionally, any kind of tools/techniques etc., particularly in Visual Studio that would give me better visibility of the request/response traffic?
I know that this is possible as it correctly adds the account ids when I use a tool like Postman:
Regarding the Tools/Techniques, you can use Fiddler to capture the request and response on the fly to check if the Raw request is correct.
If you haven't used it before, have a look here for instructions on how to capture the requests and responses.
I was able to get the json string method working by changing the StringContent encoding type from Encoding.UTF8 to null OR Encoding.Default.
string json = "{\"ids\":[10545801,10731939]}";
var httpContent = new StringContent(json, Encoding.Default, "application/json");
var response = await client.PostAsync($"{client.BaseAddress}/classifications/{classification.id}/accounts/add", httpContent);
I also figured out a way to use an object containing an int array of ids with the Encoding.UTF8;
HttpClient client = Api.GetHttpClient();
var postData = new PostData {ids = new[] {10545801,10731939}};
var json = JsonConvert.SerializeObject(postData);
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{client.BaseAddress}/classifications/{classification.id}/accounts/add", httpContent);
If you don't want to go to the trouble of creating a class just to store post data you can use an anonymous type:
var postData = new { ids = new[] {10545801,10731939}};
var json = JsonConvert.SerializeObject(postData);
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{client.BaseAddress}/classifications/{classification.id}/accounts/add", httpContent);
Try below code it will work
using (var client= new HttpClient()) {
string json = "{\"ids\":[10545801,10731939]}";
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{client.BaseAddress}/classifications/{classification.id}/accounts/add", httpContent);
// If the response contains content we want to read it!
if (response .Content != null) {
var responseContent = await response.Content.ReadAsStringAsync();
//you will get your response in responseContent
}
If this is a duplicate of any existing question, please let me know which post has a similar situation.
I am trying to call a POST API, which actually works perfectly from REST clients like POSTMAN.
When I try to call that API from C# using HttpClient, it only works if I do not use any HTML content in the request body.
Here is my code:
HttpClient client = new HttpClient();
string baseUrl = channel.DomainName;
client.BaseAddress = new Uri(baseUrl);
client.DefaultRequestHeaders
.TryAddWithoutValidation(
"Content-Type",
"application/x-www-form-urlencoded;charset=utf-8");
const string serviceUrl = "/api/create";
var jsonString = CreateApiRequestBody(model, userId, false);
var uri = new Uri(baseUrl + serviceUrl);
try
{
HttpResponseMessage response = await client.PostAsync(uri.ToString(), new StringContent(jsonString, Encoding.UTF8, "application/json"));
if (response.IsSuccessStatusCode)
{
Stream receiveStream = response.Content.ReadAsStreamAsync().Result;
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
var str = readStream.ReadToEnd();
}
...
}
And my jsonString looks like:
{
\"user_id\":\"6\",
\"description\":\"<h2 style=\\\"font-style:italic;\\\"><u><font><font>Test Test Test </font></font></u></h2>\\n\\n<p style=\\\"font-style: italic;\\\">Hi it's a Test JOB</p>\\n\\n<p> </p>\"
}
When I use plain text in description tag, the API returns a valid response, but not with the HTML content in it.
I believe I might be missing some extra header or something else.
Any help will be greatly appreciated.
Have you tried using WebUtility.HtmlEncode() method?
Where you're setting the StringContent content, try using WebUtility.HtmlEncode(jsonString) to make it API-friendly.
Like this:
using System.Net;
HttpResponseMessage response =
await client.PostAsync(
uri.ToString(),
new StringContent(WebUtility.HtmlEncode(jsonString),
Encoding.UTF8,
"application/json"));
Don't forget to use System.Net
That will give you a safe (especially for APIs) HTML string to use in your request.
Hope this helps.
I have an application that uses the outlook REST API for creating events on the user's calendar. The creation of the event works perfectly, but once I tried to to exactly as this post indicates, I get 405 Method Not Allowed.
the error details are as follow:
{"error":{"code":"ErrorInvalidRequest","message":"The OData request is not supported."}}
here's a part of my code:
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, new Uri("https://outlook.office365.com/api/v1.0/me/events/"+meeting.OutlookEventId));
var auth = "Bearer " + token;
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Authorization", auth);
var converters = new List<JsonConverter>();
converters.Add(new MyStringEnumConverter());
var createResponse = #"{
'Location': {
'DisplayName': 'Your office'
}
}";
request.Content = new StringContent(createResponse);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await client.SendAsync(request);
I have the user token sotred on the "token" variable, as well as the outlook event Id on the "meeting.OutlookEventId" variable.
Any ideas?
Thank you very much!
I feel like a total fool...
I was sending a POST when this request required a PATCH
I just replaced
HttpMethod.Post
for
new HttpMethod("PATCH")
I'm trying to access an API, but all the documentation is in PHP and I'm not very familiar with PHP. I am having trouble authenticating to the API. The documentation is here.
Here is what I have so far
var webAddress = "https://xboxapi.com/v2/latest-xbox360-games";
var httpResponse = (new HttpClient().GetAsync(webAddress)).Result;
httpResponse.EnsureSuccessStatusCode();
var jsonResponse = httpResponse.Content.ReadAsStringAsync().Result;
I'm just not sure how to add the authentication header that they are using in PHP.
Any help would be appreciated.
To add a custom header (in this case X-AUTH), you need to send a custom HttpRequestMessage. For example:
var webAddress = "https://xboxapi.com/v2/latest-xbox360-games";
HttpClient client = new HttpClient();
HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Get, webAddress);
msg.Headers.Add('X-AUTH', 'your-auth-key-here');
HttpResponseMessage response = await client.SendAsync(msg);