28

I have created a user register controller to register users with repository design pattern. My controller looks like this.

[Route("api/[controller]")]
    public class AuthController : Controller
    {
        private readonly IAuthRepository _repo;
        public AuthController(IAuthRepository repo)
        {
            _repo = repo;
        }

        [AllowAnonymous]
        [HttpPost("register")]
        public async Task<IActionResult> Register([FromBody] UserForRegisterDto userForRegisterDto){
            // validate request
            if(!ModelState.IsValid)
            return BadRequest(ModelState);

            userForRegisterDto.Username = userForRegisterDto.Username.ToLower();

            if(await _repo.UserExists(userForRegisterDto.Username)) 
            return BadRequest("Username is already taken");

            var userToCreate = new User{
                Username = userForRegisterDto.Username
            };

            var createUser = await _repo.Register(userToCreate, userForRegisterDto.Password);

            return StatusCode(201);
        }
    }

When I send a request using Postman, it gives me the the 404 not found status code, and API reports the request completed without reading the entire body.

enter image description here

My request in Postman looks like this. enter image description here

I have used Data Transfer Objects(DTO) to encapsulate data, I removed UserForRegisterDto and tried to use string username and string password, as follows but it did not work.

public async Task<IActionResult> Register([FromBody] string username, string password)

UserForRegisterDto looks like this.

 public class UserForRegisterDto
    {
        [Required]
        public string Username { get; set; }

        [Required]
        [StringLength(8, MinimumLength =4, ErrorMessage = "You must specify a password between 4 and 8 characters.")]
        public string Password { get; set; }
    }

I have tried many online solutions for this, but so far nothing resolved my problem. Please help me to troubleshoot the issue, Thank you in advance. I'm running this API on Ubuntu 18.04

Edit: Startup.cs

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<DataContext>(x => x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddCors();
            services.AddScoped<IAuthRepository, AuthRepository>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
            app.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());
            app.UseMvc();
        }
    }
Nishān Wickramarathna
  • 1,964
  • 1
  • 18
  • 28

10 Answers10

27

It happened to me in a new ASP.NET Core 2.1 service when debugging in localhost because I had in Startup.Configure:

app.UseHttpsRedirection();

I deactivated this setting when debugging locally:

if (env.IsDevelopment())
{
     app.UseDeveloperExceptionPage();
}
else
{
     app.UseHttpsRedirection();
}
Vilmir
  • 585
  • 6
  • 8
26

The error info of the application completed without reading the entire request body often occurs when the client send a request that doesn't fulfill the sever requirements . In other words , it happens just before entering the action , resulting that you cannot debug it via a breakpoint within the body of action method .

For example , let's say a action method on the server :

[Route("api/[controller]")]
[ApiController]
public class DummyController : ControllerBase
{
    [HttpPost]
    public DummyDto PostTest([FromBody] DummyDto dto)
    {
        return dto;
    }
}

The DummyDto here is a dummy class to hold information:

public class DummyDto 
{
    public int Id { get; set; }
}

When clients send a request with payload not well formatted

For example , the following post request , which doesn't have a Content-Type: application/json header :

POST https://localhost:44306/api/test HTTP/1.1
Accept : application/json

{ "id":5 }

will result in a similar error info :

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST http://localhost:44306/api/test  10
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 1.9319ms 404 
Microsoft.AspNetCore.Server.Kestrel:Information: Connection id "0HLGH8R93RPUO", Request id "0HLGH8R93RPUO:00000002": the application completed without reading the entire request body.

and the response from the server will be 404:

HTTP/1.1 404 Not Found
Server: Kestrel
X-SourceFiles: =?UTF-8?B?RDpccmVwb3J0XDIwMThcOVw5LTFcU08uQXV0aFJlYWRpbmdXaXRob3V0RW50aXRlQm9keVxBcHBcQXBwXGFwaVx0ZXN0?=
X-Powered-By: ASP.NET
Date: Mon, 03 Sep 2018 02:42:53 GMT
Content-Length: 0

As for the question you described , I suggest you should check the following list :

enter image description here

  1. does the Postman send the request with a header of Content-Type: application/json ? make sure you have checked the header
  2. If step1 doesn't work , click the code to show what it sends exactly when you send a request to the server .
itminus
  • 17,805
  • 2
  • 29
  • 60
  • 1
    Thank you @itminus. I had an issue with my directory structure of the project. Problem was my `AuthController` was not in the Controllers folder. I managed to find it because of your detailed answer. HatsOff! – Nishān Wickramarathna Oct 19 '18 at 05:22
4

There can be multiple reasons out of which one can be : – Caching in Visual Studio --

1.Close all the instances of visual studios, run Developer command prompt with Admin rights.
2.git clean -xfd [Your Repository to remove all dependencies and existing soln file]
3.take the latest build and run . [Make Endpoint AllowAnonymous]
dinesh kandpal
  • 641
  • 7
  • 12
2

I had the same error (even with "Content-Type: application/json") but adding "{id}" into the action verb worked for me i.e. changing from

    [HttpPatch]
    [ActionName("Index")]
    [Authorize(Policy = "Model")]
    public async Task<JsonResult> Update([FromRoute]int id, int modelId, [FromBody]Device device)

to

    [HttpPatch("{id}")]
    [ActionName("Index")]
    [Authorize(Policy = "Model")]
    public async Task<JsonResult> Update([FromRoute]int id, int modelId, [FromBody]Device device)

(asp.net core 2.1)

Robert
  • 31
  • 3
2

I solved it like that. From

namespace AuthenticationService.Controllers
{
    [Route("api/authentication")]
    [ApiController]
    public class AuthenticationController : ControllerBase
    {
        [HttpPost("/token")]
        public IActionResult GenerateToken([FromBody] LoginRest loginRest)
        {

to [Route("api/authentication/")] with an addional /. The slash at[HttpPost("token")] I removed.

kuzdu
  • 5,943
  • 1
  • 37
  • 56
2

Had the same issue running a Dotnet 2.2 and NGinx on remote Ubuntu 18.04-machine, got a:

.. . the application completed without reading the entire request body

on every API-call. What solved it for me was to install the SSL Certificates on the host through CERTBot from Let's encrypt, since Dotnet doesn't allow un-encrypted traffic.

Hopes this helps someone

Haroun Hajem
  • 3,122
  • 3
  • 20
  • 31
2

I spent hours on this. My problem was that I had:

[HttpPut("{matchGuidStr}/join")]
public async Task<IActionResult> JoinNewMatch (string matchGuidStr) {

instead of:

[HttpPut("{matchGuidStr}/join")]
public async Task<IActionResult> JoinNewMatch (string matchGuidStr, [FromBody] Payloads.JoinGamePayload payload) {

basically, my route didn't care about the request body at all (intentionally) but I needed to still pass it as a parameter. yikes!

dak
  • 81
  • 1
  • 5
1

Could you try it by adding a request method [Route("jsonbody")]

 [AllowAnonymous]
 [HttpPost("register")]
 [Route("jsonbody")]
    public async Task<IActionResult> Register([FromBody] UserForRegisterDto userForRegisterDto){}
0

i have same error, check maybe you put (AutoValidateAntiforgeryTokenAttribute) in AddMvc Services

services.AddMvc(opt => {

            //Prevent CSF Attake For POST,PUT,DELETE Verb
            //opt.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        })
-2

In my case, was the query wrong:

SELECT * FROM dbo.person WHERE login= 'value' && pass = 'value'

Solved after fix && wrong AND ok

SELECT * FROM dbo.person WHERE login= 'value' AND pass = 'value'
Diego Venâncio
  • 4,095
  • 2
  • 31
  • 56