Can I add [FromBody] parameter with backward compatibility?

I have endpoint which doesn't have [FromBody] parameter:

    [HttpPost("{id:int}/publish")]
    public async Task<IActionResult> Publish()
    {
        <do some stuff>
        return Ok();
    }

But now I need to add [FromBody] parameter in the way that old code is still able to use this endpoint without parameter:

    [HttpPost("{id:int}/publish")]
    public async Task<IActionResult> Publish([FromBody] PublishRequest request)
    {
        <do some stuff>
        return Ok();
    }

But if I add it in this way and try to call this endpoint with empty body, i got 415 (Unsupported Media Type) response back.

I want to make this change backward compatible. So it should be possible to use this endpoint without request body and content-type header. Is is possible?

2 answers

  • answered 2020-06-02 10:50 Marius Steinbach

    You can make the PublishRequest optional.

    [HttpPost("{id:int}/publish")]
    public async Task<IActionResult> Publish([FromBody] PublishRequest? request)
    {
        // <do some stuff>
        return Ok();
    }
    

  • answered 2020-06-02 11:06 Guru Stron

    It seems that optional FromBody parameters are not supported ATM, but in this github issue was posted a possible workaround:

    public class SomeClassModelBinder : IModelBinder
    {
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            var stream = bindingContext.HttpContext.Request.Body;
            string body;
            using (var reader = new StreamReader(stream))
            {
                body = await reader.ReadToEndAsync();
            }
            var someClass = JsonConvert.DeserializeObject<SomeClass>(body);
    
            bindingContext.Result = ModelBindingResult.Success(someClass);
        }
    }
    
    [FromBody, ModelBinder(BinderType = typeof(SomeClassModelBinder))] SomeClass request,