Search code examples
jsonasp.net-core-mvchttprequesthttpresponsebad-request

dot net Core 3.1 API HttpRequest returns usually bad request without even sending the request


I have a strange issue with my HttpRequest, i have 2 application one is clientside and the other one is RESTAPI, the issue is i am trying to update my entity by sending a request which the content is Json

 public async Task<bool> Update(string url, T obj, string id)
    {
        var request = new HttpRequestMessage(HttpMethod.Put, url+id);
        if (obj == null || String.IsNullOrEmpty(id))
        {
            return false;

        }
       
        request.Content = new StringContent(JsonConvert.SerializeObject(obj),
            Encoding.UTF8, "application/json");


        var client = _client.CreateClient();
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("bearer", GetBearerToken());

        HttpResponseMessage response = await client.SendAsync(request);
        if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
        {
            return true;
        }
        return false;

    }

And here is my clientapp controller below;

 [HttpPost]
    public async  Task<IActionResult> EditUser([FromForm] UserDTO userDTO ,string id)
    {
        if (!ModelState.IsValid)
        {
            return RedirectToAction("ErrorPage", "Error");
        }
        userDTO.Id = id;
        await _userRepository.Update(EndPoints.UserEndPoint,userDTO,id);
        return RedirectToAction("GetUsers");
    }

and i dont know if it is necessary because it doesnt hit even the breakpoint but i am also showing my RESTAPI code below;

 /// <summary>
    /// Update user
    /// </summary>
    /// <param name="id"></param>
    /// <param name="userDTO"></param>
    /// <returns></returns>   
    [HttpPut("{id}")]
    [Authorize(Roles = "Administrator")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]

    public async Task<IActionResult> UpdateUser(string id, [FromBody] UserDTO userDTO)
    {
        var location = GetControllerActionNames();

        try
        {
            _logger.LogInfo($"{location}: Requested an Update for id: {id} ");

            if (string.IsNullOrEmpty(id) || userDTO == null || id != userDTO.Id)
            {
                _logger.LogError($"{location}: Request for Id: {id} is not sucessful");
                return BadRequest();
            }

            if (!ModelState.IsValid)
            {
                _logger.LogWarn($"{location}: Data was incomplete!");
                return BadRequest(ModelState);
            }

            var isExist = await _userRepo.IsExist(id);
            if (!isExist)
            {
                _logger.LogWarn($"{location}: with Id: {id} is not exisist");
                return NotFound();
            }

            



            var usermap = _mapper.Map<CompanyUser>(userDTO);



            if (usermap == null)
            {
                _logger.LogWarn($"{location}:  Data is empty");
                return BadRequest();
            }

            var response = await _userRepo.Update(usermap);

            if (!response)
            {
                _logger.LogError($"{location}: Update is failed ");
                return NotFound();
            }
            _logger.LogInfo($"User is Updated");
            return NoContent();
        }
        catch (Exception e)
        {

            return InternalError($"{location} - {e.Message} - {e.InnerException}");
        }
    }

RESTAPI code is working when i try with PostMan. But from the client side where i send the request it sometimes works but usually gives bad request as response instanly i mean not even go to my RESTAPI. Can you help to resolve this strange problem.


Solution

  • I fixed the issue, on my API Login Because i was using Microsoft Identity and when i use await PasswordEmailSignInAsync(userName, password, false, false); it automatically genereates application cookie on my API side and i used fiddler to capture requests and i saw there when i get an error or on my API side when the thread exits the application cookie also expires after that when i made a new request from my Client to My API it was giving the bad request on my client side instantly.

    So i changed my signin method to var user = await _userManager.FindByEmailAsync(userDTO.Email); var result = await _userManager.CheckPasswordAsync(user, userDTO.Password);

    in order to avoid from the application cookie creation. I had already JWT token structure in my application but was useless because default authorized attribute was not using bearer schema and i modified my startup.cs a little help from [Authorize Attribute not working with JWT Access Token in ASP.Net Core1

    and now everything works without any problem!.

    [Route("login")]
        [HttpPost]
        [AllowAnonymous]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        public async Task<IActionResult> Login([FromBody] UserLoginDTO userDTO)
        {
    
            var location = GetControllerActionNames();
            try
            {
                var userName = userDTO.Email;
                var password = userDTO.Password;
             
                _logger.LogInfo($"{location}: User:{userName} - Attempted to Login");
                //var result = await PasswordEmailSignInAsync(userName, password, false, false);
                var user = await _userManager.FindByEmailAsync(userDTO.Email);
                var result = await _userManager.CheckPasswordAsync(user, userDTO.Password);
    
               
                if (result)
                {
                  
                    _logger.LogInfo($"{location}: User:{userName} Logged in Succesfully");
                    var tokenstring = await GenerateJSONWebToken(user);
                    return Ok(new { token = tokenstring });
                }
                _logger.LogWarn($"{location}: User:{userName} couldnt logged in ");
                return Unauthorized(userDTO);
            }
            catch (Exception e)
            {
    
                return InternalError($"{location} - {e.Message} - {e.InnerException}");
            }
        }