I want to answer all in one response when doing this job as a note for all and myself:
According to Serez's answer HttpContent derived classes list as below
https://stackoverflow.com/a/42380027/914284
HttpClient PostAsync has some background depending on the context you working on!
- You can post data by the type that you want to send to server in cases
Server context waits it as bellow
[HttpPost]
public async Task<IActionResult> Submit(MyModel model)
[HttpPost]
public async Task<IActionResult> Submit([FromForm] MyModel model)
[HttpPost]
public async Task<IActionResult> Submit([FromBody] MyModel model)
When writing FromForm or Body it has working as FromForm.
FromBody needs json content otherwise it requires KeyValuePairs as rows. There is some implementations for both of them such as below:
For FromForm: I have used an extension
public static class HelperExtensions
{
public static FormUrlEncodedContent ToFormData(this object obj)
{
var formData = obj.ToKeyValue();
return new FormUrlEncodedContent(formData);
}
public static IDictionary<string, string> ToKeyValue(this object metaToken)
{
if (metaToken == null)
{
return null;
}
// Added by me: avoid cyclic references
var serializer = new JsonSerializer { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
if (metaToken is not JToken token)
{
// Modified by me: use serializer defined above
return ToKeyValue(JObject.FromObject(metaToken, serializer));
}
if (token.HasValues)
{
var contentData = new Dictionary<string, string>();
foreach (var child in token.Children().ToList())
{
var childContent = child.ToKeyValue();
if (childContent != null)
{
contentData = contentData.Concat(childContent)
.ToDictionary(k => k.Key, v => v.Value);
}
}
return contentData;
}
var jValue = token as JValue;
if (jValue?.Value == null)
{
return null;
}
var value = jValue?.Type == JTokenType.Date ?
jValue?.ToString("o", CultureInfo.InvariantCulture) :
jValue?.ToString(CultureInfo.InvariantCulture);
return new Dictionary<string, string> { { token.Path, value } };
}
}
For FromBody: Use any json converter library Newtonsoft or microsoft
using Newtonsoft.Json;
var jsonString = JsonConvert.SerializeObject(obj);
In both of them, content type should be defined according the requirement, for example for json (Write to header)
request.Headers.Accept.Clear();
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
or another usage
using (var content = new StringContent(JsonConvert.SerializeObject(answer), System.Text.Encoding.UTF8, "application/json"))
{
var answerResponse = await client.PostAsync(url, content);
//use await it has moved in some context on .core 6.0
}
If you should use authorization on the context also you can provide authorization as below:
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Your Oauth token");