10

I have a method:

public ActionResult AddProductToCart(int productId)
    {
        var product = _productService.GetProductById(productId);
        if (product == null)
            return RedirectToAction("Index", "Home");

        int productVariantId = 0;
        if (_shoppingCartService.DirectAddToCartAllowed(productId, out productVariantId))
        {
            var productVariant = _productService.GetProductVariantById(productVariantId);
            var addToCartWarnings = _shoppingCartService.AddToCart(_workContext.CurrentCustomer,
                productVariant, ShoppingCartType.ShoppingCart,
                string.Empty, decimal.Zero, 1, true);
            if (addToCartWarnings.Count == 0)
                //return RedirectToRoute("ShoppingCart");
            else
                return RedirectToRoute("Product", new { productId = product.Id, SeName = product.GetSeName() });
        }
        else
            return RedirectToRoute("Product", new { productId = product.Id, SeName = product.GetSeName() });
    }

You see the line which is commented out: I want there to not trigger any redirect but just stay on the same page from where this request was made.

If I put return View() it's not fine because it will search for View with this name while this method is a simple action to add to cart..

Can you please give me a solution of how to Redirect to current url or to stay on the same page?

Cristian Boariu
  • 9,603
  • 14
  • 91
  • 162

2 Answers2

16

You could pass an additional returnUrl query string parameter to this method indicating the url to get back to once the product has been added to the cart:

public ActionResult AddProductToCart(int productId, string returnUrl)

so that you can redirect back to wherever you were:

if (addToCartWarnings.Count == 0)
{
    // TODO: the usual checks that returnUrl belongs to your domain
    // to avoid hackers spoofing your users with fake domains
    if (!Url.IsLocalUrl(returnUrl))
    {
        // oops, someone tried to pwn your site => take respective actions
    } 
    return Redirect(returnUrl);
}

and when generating the link to this action:

@Html.ActionLink(
    "Add product 254 to the cart", 
    "AddProductToCart", 
    new { productId = 254, returnUrl = Request.RawUrl }
)

or if you are POSTing to this action (which by the way you should probably be because it is modifying state on the server - it adds a product to a cart or something):

@using (Html.BeginForm("AddProductToCart", "Products"))
{
    @Html.Hidden("returnurl", Request.RawUrl)
    @Html.HiddenFor(x => x.ProductId)
    <button type="submit">Add product to cart</button>
}

Another possibility is to use AJAX to invoke this method. This way the user will stay on the page wherever he was before calling it.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • As "easy" as it is to grab the referrer, I think this is a better solution. It's more work up-front, but I believe it gives you a more solid result. On the slip side, you can _try_ using `returnUrl` and default to `Request.Referrer`. An almost more bullet-proof approach is to create an HtmlExtender (maybe `Html.ActionLinkWithReturnUrl(...)`?) – Brad Christie Feb 20 '12 at 20:24
  • @BradChristie, personally I don't use `Referrer`. Don't know why. Just don't like it. – Darin Dimitrov Feb 20 '12 at 20:26
  • Anything where you rely on things in a stateless environment gives me the willies too; so I'm with you. – Brad Christie Feb 20 '12 at 20:27
  • Dunno why, I am just paranoiac that there must be some IE version or something that in a particular situation won't send this HTTP header with the request and it's gonna bust my site whereas with a query string parameter I feel safer. Go blame IE, not me. It has bitten me so many times that I prefer to take precautions. I have strictly no scientific proof, just my paranoia about IE. But maybe all this is not necessary and the Referrer header will work just fine. – Darin Dimitrov Feb 20 '12 at 20:30
  • @BradChristie / Darin: See [the answers to this question](http://stackoverflow.com/questions/9283628/should-i-use-http-referrer-validation-or-token-verification-to-prevent-csrf-atta) for why relying on it is a bad idea. If it doesn't get sent in this scenario, the site would still function, but the user would be redirected to the default route (I assume). That could be pretty confusing and certainly detrimental from a usability point-of-view. – John H Feb 20 '12 at 21:44
  • I know this is old, this is for anyone who is visiting. Please use "RedirectToLocal" to prevent Open Redirection Attacks. MVC 3 or lower users, need to implement that method. http://www.asp.net/mvc/overview/security/preventing-open-redirection-attacks – Jose A May 30 '16 at 14:10
6

Assuming you mean return to where you were before visiting that controller:

return Redirect(Request.UrlReferrer.ToString());

Keep in mind that if you POSTed to get to that [previous] page, you're going to be at a loss since you're not mimicking the same request.

Brad Christie
  • 100,477
  • 16
  • 156
  • 200