Reputation: 73
I am trying to write a webapi using .net core 2.2. I have a controller and I am trying to send a request from postman to this endpoint.
[Route("data/[controller]")]
[Produces("application/json")]
[ApiController]
public class MatchesController : ControllerBase
{
private readonly ILog _log;
private readonly IMatchesService _matchesService;
private readonly IMapper _mapper;
public MatchesController(ILog log, IMatchesService matchService, IMapper mapper)
{
_log = log;
_matchesService = matchService;
_mapper = mapper;
}
// POST: data/Matches
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> PostMatches([FromBody]DataMatch match)
{
if (match == null)
return BadRequest("You cannot add a 'null' match");
var m = _mapper.Map<DataMatch, Match>(match);
match.Id = await _matchesService.AddMatchAsync(m);
return CreatedAtAction("PostMatches", match);
}
[HttpGet]
public async Task<IActionResult> GetMatches()
{
var a = 3;
Match match = new Match { Id = a };
//match.Id = await _matchesService.AddMatchAsync(match);
return CreatedAtAction("GetMatches", match);
}
The get request works fine, but the POST request model does not bind correctly. Here is the DataMatch model
public class DataMatch
{
public int? Id { get; set; }
public string League { get; set; }
public string HomeTeam { get; set; }
public string AwayTeam { get; set; }
//public DateTime Time { get; set; }
}
and the request I am trying to send from Postman is
{
"id": 3,
"league":"PL",
"country":"England",
"away_team":"Man City",
"home_team":"Everton"
}
with content-type as "application/json". I can hit the POST endpoint with the request, so it is not a routing issue, but the match object is always null. I have enabled the following server settings in the Startup.cs file.
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options =>
{
var settings = options.SerializerSettings;
settings.ContractResolver = new CustomJSONSerializer();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
settings.NullValueHandling = NullValueHandling.Ignore;
}).ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.SuppressUseValidationProblemDetailsForInvalidModelStateResponses = true;
})
In postman I get a 400 Error, but I have been able to discover a more in-depth 'body cannot be empty' error thrown by the framework/server somewhere along the way.
Upvotes: 0
Views: 1127
Reputation: 73
I have managed to find the solution and the issue was that I had an endpoint logging middleware which was consuming the stream so the parameter would always be null in the controller. The correct solution is either to reset the stream in the middleware or not to use it
Upvotes: 2
Reputation: 4236
You have two options.
Add JsonProperty attribute on HomeTeam and AwayTeam properties on DataMatch class:
[JsonProperty("away_team")]
public string AwayTeam {get;set;}
[JsonProperty("home_team")]
public string HomeTeam {get;set;}
In the json that you are posting change key names remove underscore _
{
"id": 3,
"league":"PL",
"country":"England",
"awayteam":"Man City",
"hometeam":"Everton"
}
Note: The issue is caused because you are using a custom IContractResolver
implementation so you need to debug CustomJsonSerializer. If you comment out the following line of code then DataMatch posted parameter will not be null.
settings.ContractResolver = new CustomJsonSerializer()
Upvotes: 0