I'm calling an API using HTTP POST with a form URL encoded body
The controller I'm calling looks like this:
public async Task<IHttpActionResult> DoSomethingAsync(ABCRequest widget)
[DataContract]
public class ABCRequest
{
[DataMember(Name="name")]
public string Name { get; set; }
[DataMember(Name="number")]
public string Number { get; set; }
}
I can happily call the API using the following method
var formData = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Name", "John"),
new KeyValuePair<string, string>("Number", "123")
};
HttpContent content = new FormUrlEncodedContent(formData);
Another API endpoint uses
public async Task<IHttpActionResult> DoSomething2Async(ABCRequest2 widget)
[DataContract]
public class ABCRequest2
{
[DataMember(Name="name")]
public string Name { get; set; }
[DataMember(Name="number")]
public string Number { get; set; }
[DataMember(Name="metadata")]
public List<KeyValuePair<string, string>> Metadata { get; set; }
}
How do I form URL encode the child List?
How do I form URL encode the child List?
According ot your scenario and description along with the share code snippet, I have tried to simulate your scenario and I was able to send send child metadata list with URL encoded value.
In order to form URL encoded child list of KeyValuePair<string, string> in your ABCRequest2 class
, you need to flatten the structure into key-value pairs that can be properly encoded.
First of all, you need to convert the child list into individual key-value pairs where each pair has a unique key representing its position or specific identifier.
After constructing the key-value pairs, have to use FormUrlEncodedContent to encode the flat list.
Let's have a look in practice, how we could achieve that:
From a key value pairs encoded content:
var formData = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("name", "John"),
new KeyValuePair<string, string>("number", "123")
};
var metadataList = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("key1", "value1"),
new KeyValuePair<string, string>("key2", "value2")
};
for (int i = 0; i < metadataList.Count; i++)
{
formData.Add(new KeyValuePair<string, string>($"metadata[{i}].Key", metadataList[i].Key));
formData.Add(new KeyValuePair<string, string>($"metadata[{i}].Value", metadataList[i].Value));
}
HttpContent content = new FormUrlEncodedContent(formData);
using (var client = new HttpClient())
{
var response = await client.PostAsync("https://localhost:7246/api/Receiving/ReceiveData", content);
if (response.IsSuccessStatusCode)
{
var responseData = await response.Content.ReadAsStringAsync();
return Ok(responseData);
}
return BadRequest("Failed to send data");
}
Receiving Controller:
[Route("api/[controller]")]
[ApiController]
public class ReceivingController : ControllerBase
{
[HttpPost]
[Route("ReceiveData")]
public async Task<IActionResult> ReceiveData([FromForm] ABCRequest2 widget)
{
return Ok(widget);
}
}
Note: Please refer to this official document for additionl reference and sample