.net核心api端点在请求后不绑定复杂数据

时间:2019-08-10 22:20:45

标签: asp.net http post asp.net-web-api

我正在尝试使用.net core 2.2编写webapi。我有一个控制器,我试图将邮递员的请求发送到此端点。

 [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);
        }

get请求工作正常,但是POST请求模型未正确绑定。这是DataMatch模型

 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; }
    }

我想从邮递员发送的请求是


    {
         "id": 3,
     "league":"PL",
     "country":"England",
     "away_team":"Man City",
     "home_team":"Everton"
    }

,内容类型为“ application / json”。我可以使用该请求来访问POST端点,因此这不是路由问题,但是match对象始终为null。我已经在Startup.cs文件中启用了以下服务器设置。

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;
                    })

在邮递员中,我收到400错误,但是我能够发现框架/服务器在此过程中某处引发的更深入的“主体不能为空”错误。

2 个答案:

答案 0 :(得分:0)

您有两个选择。

在DataMatch类的HomeTeam和AwayTeam属性上添加JsonProperty属性:

[JsonProperty("away_team")]
public string AwayTeam {get;set;}

[JsonProperty("home_team")]
public string HomeTeam {get;set;}

在您发布更改名称的json中,删除下划线_

{
     "id": 3,
 "league":"PL",
 "country":"England",
 "awayteam":"Man City",
 "hometeam":"Everton"
}

注意:引起此问题的原因是您使用的是自定义IContractResolver实现,因此需要调试CustomJsonSerializer。如果您注释掉以下代码行,那么DataMatch发布的参数将不会为null。

settings.ContractResolver = new CustomJsonSerializer()

答案 1 :(得分:0)

我设法找到了解决方案,问题是我有一个端点记录中间件正在消耗流,因此该参数在控制器中始终为null。正确的解决方案是重置中间件中的流或不使用它