Search code examples
.netangularpostmanangular7

Media Type Not Supported 415 from Angular 7 SPA to .NET, while request is working in Postman


When my SPA makes a call to a specific endpoint in my .NET API, which I recently added pagination to, I get a 415 Unsupported Media Type Error, however, when I make the same call from Postman, it is successfully executed. I am not sure why I would be getting an error from the SPA for an identical call in postman.

I have tested the endpoint from Postman, and discovered that it is working, and verified that I am calling the same endpoint from my SPA.

Frontend Call:

  fetchChanges(page?, itemsPerPage?){
    const paginatedResult: PaginatedResult<Change[]> = new PaginatedResult<Change[]>();

    let params = new HttpParams();

    if (page != null && itemsPerPage != null){
      params = params.append("pageNumber", page);
      params = params.append("pageSize", itemsPerPage);
    }

      return this.http.get(
        this.apiUrl + '/changelog/' + this.model, { observe: "response", params })
        .pipe(
          map((responseData: any) => {
            paginatedResult.result = responseData.body;
            if (responseData.headers.get("Pagination") != null){
              paginatedResult.pagination = JSON.parse(responseData.headers.get("Pagination"));
            }
              return paginatedResult;
          })
        )
  }

Controller function for the endpoint:


        [HttpGet("{model}")]
        public async Task<IActionResult> GetChangeLog(int userId, string model, ChangeLogParams changeLogParams)
        {
            if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
                return Unauthorized();

            var changeLog = await _repo.GetChangeLog(userId, model, changeLogParams);

            var changeLogForReturn = _mapper.Map<IEnumerable<ChangelogForReturnDto>>(changeLog);

            Response.AddPagination(changeLog.CurrentPage, changeLog.PageSize, changeLog.TotalCount, changeLog.TotalPages);

            return Ok(changeLogForReturn);
        }

I expect the frontend to execute the request, and returned paginated results.enter image description here

The code for the app can be found here: https://github.com/DomTripodi93/ProductionDotNet


Solution

  • After examining my headers I realized I was setting my content to JSON in Postman, something Angular "post"/"put"/"patch" does automatically, but not "get" of course. This made me realize that I still had my login request body set in Postman. After clearing the body, I got a 400 "request-body cannot be set null" error, which made me realize that for some reason my endpoint was expecting a request-body with my "get" request.

            [HttpGet("{model}")]
            public async Task<IActionResult> GetChangeLog(int userId, string model, ChangeLogParams changeLogParams)
            {
                if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
                    return Unauthorized();
    
                var changeLog = await _repo.GetChangeLog(userId, model, changeLogParams);
    
                var changeLogForReturn = _mapper.Map<IEnumerable<ChangelogForReturnDto>>(changeLog);
    
                Response.AddPagination(changeLog.CurrentPage, changeLog.PageSize, changeLog.TotalCount, changeLog.TotalPages);
    
                return Ok(changeLogForReturn);
            }
    

    After looking back over the code I found that the issue was my ChangeLogParams argument in the backend being expected as a request body.

    Adding [FromQuery] to the ChangeLogParams argument, to get my paging data from the params instead of the request body, has resolved my issue.

            [HttpGet("{model}")]
            public async Task<IActionResult> GetChangeLog(int userId, string model, [FromQuery]ChangeLogParams changeLogParams)
            {
                if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
                    return Unauthorized();
    
                var changeLog = await _repo.GetChangeLog(userId, model, changeLogParams);
    
                var changeLogForReturn = _mapper.Map<IEnumerable<ChangelogForReturnDto>>(changeLog);
    
                Response.AddPagination(changeLog.CurrentPage, changeLog.PageSize, changeLog.TotalCount, changeLog.TotalPages);
    
                return Ok(changeLogForReturn);
            }