Search code examples
c#.netauthorize

http 405 after use [Authorize] and login


I am writing a simple pet online shop website and I was trying to check user login status if they press the add to cart button, and if they logged in they are able to add the product to cart, if they not log in, they will redirect log in page and login first then do all the function, I am using .NET Core found there is [Authorize] function, so I just put this front of my AddToCart method, however I found a issue is if user not login, press button will lead the login page, and once logged in, the URL will go to https://localhost:7281/Carts/AddtoCart?productId=4 (because I press the product that id =4) and shows http405, but if i manually go back to home page, because is already logged in, i press the button again, is working fine and go to the carts index page, so the question is how could page can go carts index page at the first time? it seems like even I logged in the computer still can't detect I logged in, I need to manually go back the page and do it again, every one had same issue before? here is my AddToCart code

        [Authorize]
        [HttpPost]
        public async Task<IActionResult> AddToCart(int productId)
        {
            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);

            var cart = await _context.Carts
                .Include(c => c.CartItems)
                .ThenInclude(ci => ci.Products)
                .FirstOrDefaultAsync(c => c.UserId == userId);

            var product = await _context.Products.FindAsync(productId);

            if (cart == null)
            {
                cart = new Cart { UserId = userId };
                cart.CartItems = new List<CartItem> { new CartItem { Products = product, Quantity = 1 } };
                _context.Carts.Add(cart);
            }
            else
            {
                var cartItem = cart.CartItems.FirstOrDefault(ci => ci.Products.Id == productId);
                if (cartItem == null)
                {
                    cart.CartItems.Add(new CartItem { Products = product, Quantity = 1 });
                }
                else
                {
                    cartItem.Quantity += 1;
                }
            }

            await _context.SaveChangesAsync();

            return RedirectToAction("Index", "Carts", new { area = "", page = "index" });

        }

Solution

  • In your case, you can check for the ReturnUrl that is generated when the user is not logged in and is redirected to login page:

    [Authorize]
    [HttpPost]
    public async Task<IActionResult> AddToCart(int productId)
    {
        string returnUrl = HttpContext.Request.Query["ReturnUrl"];
        if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
        {
            return RedirectToAction("Index", "Carts", new { area = "", page = "index" });
        }
           
        var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
    
        var cart = await _context.Carts
            .Include(c => c.CartItems)
            .ThenInclude(ci => ci.Products)
            .FirstOrDefaultAsync(c => c.UserId == userId);
    
        var product = await _context.Products.FindAsync(productId);
    
        if (cart == null)
        {
            cart = new Cart { UserId = userId };
            cart.CartItems = new List<CartItem> { new CartItem { Products = product, Quantity = 1 } };
            _context.Carts.Add(cart);
        }
        else
        {
            var cartItem = cart.CartItems.FirstOrDefault(ci => ci.Products.Id == productId);
            if (cartItem == null)
            {
                cart.CartItems.Add(new CartItem { Products = product, Quantity = 1 });
            }
            else
            {
                cartItem.Quantity += 1;
            }
        }
    
        await _context.SaveChangesAsync();
    
        return RedirectToAction("Index", "Carts", new { area = "", page = "index" });