Asp.Net httpGet get httpstatus 415 for calling controller method with complex type parameter

Viewed 84

I have an angular client that is sending an HttpRequest to server to get client informations:

 getClient(roleId): Observable<ClientDto> {

      let params = new HttpParams();
      params = params.append('Id', clientId); 

      return this._httpClient.get<ClientDto>('myurl', {params});
    }

and on the controller I have

    [HttpGet]
    public async Task<ActionResult<ClientDto>> GetClient(EntityDto<int> data)
    {
        return Ok(await clientsService.GetClient(data.Id));
    }

    public class EntityDto : EntityDto<int>, IEntityDto
    {
        public EntityDto()
        {

        }

        public EntityDto(int id)
            : base(id)
        {
        }
    }

    public class EntityDto<TKey> : IEntityDto<TKey>
    {
        [Required]
        public TKey Id { get; set; }

        public EntityDto()
        {

        }

        public EntityDto(TKey id)
        {
            Id = id;
        }
    }
 public interface IEntityDto : IEntityDto<int>
    {

    }

    public interface IEntityDto<TKey>
    {
        /// <summary>
        /// Id of the entity.
        /// </summary>
        TKey Id { get; set; }
    }

When I make the call from angular I receive an Http status 415 response Does any one knows why this happers?

2 Answers

Generally it is a good idea to add the ID for the resource you are requesting to the request path eg: /books/1 this will return book with an id of one, is there a reason you are have the id added as a query string?

To answer your comment: query strings are generally used for filtering or pagination and it is not searched by default, you need to add [FromQuery].

I advice sending the id of your resource as part of your request.

you retrieve it like so:

[HttpGet("{id})"]
public async Task<ActionResult<ClientDto>> GetClient(int id, [FromQuery] string fields)
{
}

here the id is contained as part of the route.

eg: /client/10

any filtering you want is contained in the query string (your angular HttpParams) eg if you just want one field from the resource you can add it as a query string

I'm going to assume that you're using [ApiController], which I think you must be in order to see the behaviour you've described. With this attribute in place, the model-binding rules for complex types changes from the default.

It's as though you specified [FromBody] on the EntityDto<int> property. When [FromBody] is applied, the model-binding process looks at the Content-Type header provided with the request. The value of this header is used when selecting an Input Formatter - at the simplest level, it would match e.g. application/json to a JSON Input Formatter. If the header is missing or does not contain a supported value, a 415 Unsupported Media Type response is sent.

You already know the solution, which is to override the inference with a binding-source attribute:

public async Task<ActionResult<ClientDto>> GetClient([FromQuery] EntityDto<int> data)

I hope this answer serves as an explanation as to why this is needed.

Related