How we can use ASP.NET Core Web API with JS fetch?

Viewed 1099

I'm trying to create a simple authorization form. Currently I'm using JS fetch to send POST request to the server, but as response I get nothing, but sometimes it works (can't explain why).

If I use Postman, I can get response from the server, but if I use JS fetch, the server throws this strange exception (can't google it):

fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HM4R02V04GJV", Request id "0HM4R02V04GJV:00000003": An unhandled exception was thrown by the application.
System.IO.IOException: The client reset the request stream.

at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.ReadAsyncInternal(Memory1 destination, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.DrainAsync(Stream stream, ArrayPool1 bytePool, Nullable`1 limit, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value, Object container)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<g__Bind|0>d.MoveNext()

Chrome console

Postman

As you can see - if I try do to this action few times - it works.

JS code:

function AuthRequest(){
let uname = document.querySelector('#username').value;
let pwd = document.querySelector('#pwd').value;

var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({"Username":uname,"Password":pwd});

var requestOptions = {
    
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://localhost:5001/api/auth/login", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));}

Controller code:

[HttpPost("login")]
    public async Task<ActionResult<string>> Login([FromBody] LoginForm loginForm)
    {
        var user = await _db.Users.FirstOrDefaultAsync(x => x.Username == loginForm.Username);

        var message = user == null ? "Can't find this user" : $"Found user {user.Username}";

        return message;
    }

UPD:

Full request data from Chrome console

Startup.cs configuration

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHsts();
        
        app.UseRouting();

        app.UseAuthorization();
        
        app.UseHttpsRedirection();
        app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
0 Answers
Related