ASP.NET MVC POST waiting indefinitely on first try

I have a standard form created with Html.BeginForm that submits to an asynchronous action in a controller. It looks like this (this is the outline, not the actual code):

    [HttpPost]
    public async Task<ActionResult> Index(UserCreds creds)
    {
        try
        {
            if (ModelState.IsValid)
            {
                var user = await loginRep.Login(creds.Username, creds.Password);

                if (user != null)
                {
                     _context.SetAuthenticationToken(user);

                     return RedirectToAction("Index", "Landing");
                } 
                else
                {
                    ModelState.AddModelError("", "Login failed.");
                }
            }
            else
            {
                _logger.Debug(string.Format("User failed authentication."));
            }

        }
        catch (Exception ex)
        {
            throw new HttpException(500, string.Format("An error occured during the execution of the action {0} from Controller {1}", "Index", "Login"), ex);
        }

        return View();
    }

      

The first time the form is submitted, the browser will wait indefinitely for a response, although you can see how the debugger step is achieved in RedirectToAction. If you then stop the request in the browser and just send it again, a redirect occurs. All subsequent login attempts are also redirected successfully. The authentication token is also somehow not set during the first attempt.

This is probably due to the use of the delegate internally loginRep.Login

. Internally, it ends up doing something like this:

private async Task<LoginResponse> SendLoginRequest(string username, string password)
{
    TaskCompletionSource<LoginResponse> tcs = new TaskCompletionSource<LoginResponse>();

    LoginResponseCallback callback = null;
    callback = new LoginResponseHandler(delegate (response) {
       securityService.OnLoginResponse -= callback;
       tcs.SetResult(response);        
    });

    securityService.OnLoginResponse += callback;

    securityService.SendLoginRequest(username, password);

    return await tcs.Task;
}

      

Does anyone understand what is going on? If it was a dead end, I would not expect the debugger to reach the redirect, and I would not expect the login to work for all attempts other than the first one.

Note that the form works the first time if you just skip submitting the login request and just specify what a successful response will be.

+3


source to share


1 answer


Ok. The problem was solved. There was nothing wrong with the two code examples I showed. The error was in the configuration of the security service, so it was unfortunately quite specific to this application.



However, the infinite wait happened because the Application_Error in Global.asax.cs was efficiently absorbing certain exceptions. As soon as I changed it to always redirect to my error page, no matter at least it is immediately redirected to the error page when the problem occurred, instead of hanging from the user's point of view.

+2


source







All Articles