I am using OData v4 in an ASP.NET application. Every time I use Postman to post to my endpoint, I get the following error. The issue is with this line public IHttpActionResult Post([FromBody] HolidayPost data)
because the function will run when I remove [FromBody] HolidayPost data
. I cannot seem to get my POST body to align with the HolidayPost
model. I am not sure what I am doing wrong.
Message
"No MediaTypeFormatter is available to read an object of type 'HolidayPost' from content with media type 'application/json'.",
type
System.Net.Http.UnsupportedMediaTypeException
stacktrace
" at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable
1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable
1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)"
My Postman POST request
- URL:
http://localhost/PortOData4/Holidays
- Headers:
Content-Type: application/json
- Body:
{
"Dates": "[\"2022-01-20T00:00:00.000-06:00\",\"2022-02-20T00:00:00.000-06:00\",\"2022-03-23T00:00:00.000-05:00\"]",
"apikey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
WebApiConfig.cs
namespace PortalogicOData
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableCors();
// Create OData entities
ODataModelBuilder builder = new ODataConventionModelBuilder();
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null); // enable OData Model Bound Attributes
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
builder.EntitySet<Holiday>("Holidays");
// map entities
config.MapODataServiceRoute("ODataRoute", null, builder.GetEdmModel());
}
}
}
HolidaysController.cs
namespace PortalogicOData.Controllers
{
[EnableCors("*", "*", "*")]
public class HolidaysController : ODataController
{
private readonly HolidayService m_service = new HolidayService();
[EnableQuery]
public IList<Holiday> Get([FromUri] string apikey)
{
if (GenericHelper.ValidateApi(apikey))
{
return m_service.Getdata(); // this works fine
}
else
{
return null;
}
}
[HttpPost]
public IHttpActionResult Post([FromBody] HolidayPost data)
{
// this function fails to execute everytime
}
}
}
HolidaysService.cs
namespace PortalogicOData.Business
{
public class HolidayService
{
public List<Holiday> Holidays => Getdata();
public List<Holiday> Getdata()
{
// this works fine
}
public Holiday Update(HolidayPost data)
{
// my update code
}
}
}
HolidayPost.cs
namespace PortalogicOData.Models
{
public class HolidayPost
{
public string apikey { get; set; }
public string Dates { get; set; }
}
}
Holiday.cs
namespace PortalogicOData.Models
{
public class Holiday
{
public int HolidayID { get; set; }
public string FunctionResult { get; set; }
public int ReturnCode { get; set; }
public DateTime Date { get; set; }
}
}
CodePudding user response:
Apparently, OData ASP.NET forces you to only allow the body in the format of route Type (e.g. Holiday
not HolidayPost
). I had to create a Generic class path used for posts instead. That is easier than trying to figure out how to use OData actions and functions.