1
Undocumented
TypeError: Window.fetch: HEAD or GET Request cannot have a body.

The C# code in the controller. It won't even hit my debug point at var results.

    [HttpGet(Name = "GetAccountBalance")]
    public async Task<ActionResult<BankTransactionDto>> GetAccountBalance(BankTransactionDto bankDto)
    {
        var results = await _bankTransactionService.GetTotalBalance(bankDto);
        return Ok(results);
    }

enter image description here

Md Farid Uddin Kiron
  • 16,817
  • 3
  • 17
  • 43
software is fun
  • 7,286
  • 18
  • 71
  • 129
  • Does this answer your question? [Swagger TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body](https://stackoverflow.com/questions/48749252/swagger-typeerror-failed-to-execute-fetch-on-window-request-with-get-head) – Patrick Jan 18 '23 at 00:20
  • The problem is your DTO as a parameter. This will be interpreted as `[FromBody]` and GET requests can't have a body. See the duplicate link I noted. – Patrick Jan 18 '23 at 00:21
  • What should it be if not HttpGet? I need to pass the account Dto to the backend so that I can look it up and obtain the results – software is fun Jan 18 '23 at 00:24
  • You can force it to pass the DTO via the query string by appending `[FromQuery]` to it, as shown in that duplicate answer. Otherwise you would need to change it to a `POST`. `GET` specification doesn't accept a body. It's not forbidden but Swagger in your case doesn't like it. – Patrick Jan 18 '23 at 00:26

3 Answers3

1

Undocumented TypeError: Window.fetch: HEAD or GET Request cannot have a body.The C# code in the controller. It won't even hit my debug point at var results.

Issue Reproduced:

I have tried to reproduce your issue and successfully simulated as expected. As you can see below:

enter image description here

Why Not Working:

Well, the error you are getting is pretty obvious in reagrds of swagger and Http verb GET as Body payloads are not supported by swagger in a GET operation, and is typically not supported by any server frameworks for instance asp.net core web api, even though the http specification is vague about supporting them.

Swagger and asp.net core web api only allow request body on POST, PUT, and PATCH request.

Solution:

Using model binding we can force asp.net controller to accept request body in HttpGET request. Specifically, we can use [FromQuery] to pass your BankTransactionDto and it will accept the body thus, hit your debugger point. You could update your code as following:

    [Route("api/[controller]")]
    [ApiController]
    public class BankTransactionController : ControllerBase
    {

        [HttpGet(Name = "GetAccountBalance")]
        public async Task<ActionResult<BankTransactionDto>> GetAccountBalance([FromQuery] BankTransactionDto bankDto)
        {
            var results = await _bankTransactionService.GetTotalBalance(bankDto);
            return Ok(bankDto);
        }
    }
    public class BankTransactionDto
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public decimal Amount { get; set; }
    }

Note: You can use [HttpGet("GetAccountBalance")]If you want your swagger URL to display as like /api/BankTransaction/GetAccountBalance

Output:

enter image description here

Note: If you need more information, you could refer to following official documnet.

  1. Asp.net core web API Http verb Request Body format.
  2. Swagger Request Body documnt
Md Farid Uddin Kiron
  • 16,817
  • 3
  • 17
  • 43
0

Change the Action Method definition to something like this:

[HttpGet("{id}")]
public async Task<ActionResult<BankTransactionDto>> GetAccountBalance(int id)
{
    // Your code here, but changed to use the `id` value.
}

where id is the technical Id of the bank transaction.

It makes no sense to try to send an entire BankTransactionDto object to the Action Method if you want to retrieve one of such objects. All it needs is a value that uniquely identifies it and with which the BankTransactionDto can be retrieved, such as the id.

It could be that Swagger will now no longer show the Request.body area (not at my Dev PC right now, so I can't try). If it does still show it, then leave it empty.
Instead put a useful and valid id in the URL, like this: /api/BankTransaction/123.

Peter B
  • 22,460
  • 5
  • 32
  • 69
0

You can't send a json with a GET request, because, as the error message specifies, it cannot have a body for historical reasons.

There's a proposal for a QUERY type request that will be similar to GET be will be able to include a body.

For now, you are limited to use other http verbs that accept bodies, or change the way you receive data to query parameters. For the later, you need to include the [FromQuery] decorator on your action parameter

public async Task<ActionResult<BankTransactionDto>> GetAccountBalance([FromQuery] BankTransactionDto bankDto)
{
    var results = await _bankTransactionService.GetTotalBalance(bankDto);
    return Ok(results);
}

And your request will have to be sent as

GET https://localhost:{port}/api/BankTransaction?id=0&bankId=0&customerId=0&transactionType=0&amount=0&memo=string

Ortiga
  • 8,455
  • 5
  • 42
  • 71