Hi,
I have an application in .Net 6 that contains a asp.net core Web API and a Winform .Net 6 test program to consume the API.
When I perform a Post I always get the error: Unsupported Media Type.
If I use the swagger page and test the Post command than it works just fine.
This is the code from the web API controller:
[Route("Persons/PostPersons")]
[HttpPost]
public void PostPersons([FromBody] Persons value)
{
PersonList.Add(value);
}
This is the entire controller:
namespace WebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
public List<Persons> PersonList = new();
// GET: api/<ValuesController>
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<ValuesController>/5
[HttpGet("{id}")]
public string Get(int id)
{
string retVal = "return value";
switch (id)
{
case 1:
retVal = "return value: 1";
break;
case 2:
retVal = "return value: 2";
break;
case 3:
retVal = "return value: 3";
break;
default:
break;
}
return retVal;
}
//sample for having multiple get commands
[Route("Blabla/GetBlabla")]//[Route("/Blabla/GetBlabla/{userId:int}/{age:int}")]//for passing 2 vars
[HttpGet]
public string GetBlabla()//Blabla/GetBlabla(int userId, int age)//for passing 2 vars ====> calling the getcommand: http://localhost:12345/api/Values/GetBlabla/23/39
{
return "Blabla";
}
[Route("Persons/GetPersons")]
[HttpGet]
public IEnumerable<Persons> GetPersons()
{
Persons john = new()
{
FirstName = "John",
LastName = "De Vries",
ID = "1"
};
Persons jimmy = new()
{
FirstName = "Jimmy",
LastName = "Van Ver",
ID = "2"
};
PersonList.Add(john);
PersonList.Add(jimmy);
return PersonList.ToArray();
}
// POST api/<ValuesController>
[HttpPost]
public void Post([FromBody] string value)
{
}
[Route("Persons/PostPersons")]
[HttpPost]
public void PostPersons([FromBody] Persons value)
{
PersonList.Add(value);
}
// PUT api/<ValuesController>/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/<ValuesController>/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
In my WinForm application I have some radio buttons and a testbutton.
So when I select the radio button: PersonsPost the last CASE code becomes activated:
private async void btnApiTest_Click(object sender, EventArgs e)
{
switch (SelectedTest)
{
case SelectedTestEnum.BlablaGet:
SelectedController = SelectedControllerEnum.Values;
rtbResult.Text = await GetDataFromApi("/Blabla/GetBlabla");
break;
case SelectedTestEnum.ValuesGet:
SelectedController = SelectedControllerEnum.Values;
rtbResult.Text = await GetDataFromApi("");
break;
case SelectedTestEnum.ValuesPlusIDGet:
SelectedController = SelectedControllerEnum.Values;
rtbResult.Text = await GetDataFromApi("", tbValuesID.Text);
break;
case SelectedTestEnum.WeatherForecastGet:
SelectedController = SelectedControllerEnum.WeatherForecast;
rtbResult.Text = await GetDataFromApi("");
break;
case SelectedTestEnum.PersonsGet:
SelectedController = SelectedControllerEnum.Values;
rtbResult.Text = await GetDataFromApi("/Persons/GetPersons");
break;
case SelectedTestEnum.PersonsPost:
SelectedController = SelectedControllerEnum.Values;
rtbResult.Text = await PostDataToApi("/Persons/PostPersons");
break;
}
}
public static async Task<string> PostDataToApi(string urlExtension)
{
string baseController = BaseUrlValuesController;
using (HttpClient client = new())
{
var formDictionary = new Dictionary<string, string>();
formDictionary.Add("FirstName", "John");
formDictionary.Add("LastName", "Rock");
formDictionary.Add("ID", "JR");
var formContent = new FormUrlEncodedContent(formDictionary);
client.BaseAddress = new Uri(baseController + urlExtension);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using HttpResponseMessage res = await client.PostAsync(baseController + urlExtension, formContent);
using HttpContent content = res.Content;
string data = await content.ReadAsStringAsync();
if (data != null)
{
return PresentReadableJson(data);
}
}
return string.Empty;
}
public static string PresentReadableJson(string json)
{
try
{
JToken parseJson = JToken.Parse(json);
return parseJson.ToString(Formatting.Indented);
}
catch
{
return json;//This is not json formatted
}
}
The baseController + urlExtension is exactly the same as what swagger uses (https://localhost:7233/api/Values/Persons/PostPersons), so I think that is not the problem.
I hope someone can help me, I tried several options, but the problem remains.
If I test the swagger page than (I have a breakpoint at PostPersons) the debugger halts at PostPersons.
However if I perform my own Post command, the debugger doesn't.
This is the swagger page: