views:

65

answers:

1

In an ASP.NET MVC application I have a CartController with this AddToCart action:

public RedirectToRouteResult AddToCart(Cart cart, decimal productId,
    string returnUrl)
    {
        Product product = productsRepository.Products
            .FirstOrDefault(p => p.prodID == productId);
        cart.AddItem(product);
        return RedirectToAction("Index", new { returnUrl });
    }

When a user submits a POST request ("Add to Cart" button) to this action from a plain ASP.NET MVC view, everything goes well: the Product is added to the Cart and the user is automatically redirected to a Cart/Index page.

If the product is submitted from a Silverlight app (which is inside an ASP.NET MVC view) it is successfully added to the Cart as well, but the there is no redirection in this case.

What is the problem? Maybe it is due to the fact that all requests from a Silverlight are asynchronous (if I'm not mistaken), and the request from a general ASP.NET MVC view is synchronous by nature? How it can affect the redirection?

In any case, how this problem could be solved?

Edited (added):

My code for sending a post request from a Silverlight app:

//first build a "paramstring" in the format "productId=126504" and then post it using this     
WebClient wc = new WebClient();
        wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
        wc.UploadStringAsync(new Uri("http://localhost:10930/Cart/AddToCart"), "POST", paramstring, "http://localhost:10930/Products");
+1  A: 

The WebClient you are using to send the POST request will automatically follow the redirects performed on the server and return the HTML and everything ends in the success callback. If you want to redirect the user browser to this page you shouldn't use WebClient. You need javascript to submit a <form>. Silverlight allows you to execute javascript, so you could use it to dynamically generate and submit a form, or if the form already exists in the DOM set the values of the input fields and submit it.

Here's an example of how you could do this. Add the following javascript function to the same page hosting the Silverlight application:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">
    function addToCart(productId, returnUrl) {
        var form = $(document.createElement('form'))
        .attr('action', '/products/addtocart')
        .attr('method', 'post')
        .append(
            $(document.createElement('input'))
                .attr('type', 'hidden')
                .attr('name', 'productId')
                .val(productId)
        )
        .append(
            $(document.createElement('input'))
                .attr('type', 'hidden')
                .attr('name', 'returnUrl')
                .val(returnUrl)
        );
        $('body').append(form);
        form.submit();
    }
</script>

And then inside your Silverlight application whenever you decide to invoke the POST action:

HtmlPage.Window.Invoke("addToCart", "123", "http://example.com/someReturnUrl");

You may add other parameters if necessary.

Darin Dimitrov
Thank you, Darin, for the great answer! Yes, it works. Just a question, is such an approach just a workaround for this particular problem, or using JavaScript for POST (or any) requests in Silverlight is a good practice and recommended approach? +1
rem
This is not a workaround. It is a good approach.
Darin Dimitrov
Darin, thank you! I wanted to ask a help about editing the JavaScript function, but decided it would be better to put it in another post http://stackoverflow.com/questions/3747222/javascript-post-request
rem