views:

374

answers:

1

I have an ASP.Net questionnaire application that resubmits data to the same page, showing a different question each time. There are BACK and NEXT buttons to navigate between questions.

I would like to detect when the form is submitted due to a browser refresh vs. one of the buttons being pressed. I came across a WebForms approach but don't know how to apply those principals in an MVC 2 application since page events aren't available (as far as I know... I'm pretty new to Microsoft's MVC model).

How would one apply that principle to MVC 2? Is there a better way to detect refresh?

+1  A: 

You could use the redirect-after-post pattern with TempData. Example:

  1. The Back and Next buttons POST a form to a controller action
  2. The controller action puts some state into the TempData and redirects to another controller action which will verify that the data is in TempData and return the view
  3. The user presses F5 on the browser, the previous action is called on GET and as the state is no longer into TempData you know the user pressed F5 and didn't pass through the form submission.

And to illustrate this:

public class HomeController: Controller
{
    public ActionResult Index()
    {
        var state = TempData["state"];
        if (state == null) 
        {
            // the user directly arrived on this action without passing 
            // through the form submission
        }
        return View();
    }

    [HttpPost]
    public ActionResult Index(string back)
    {
        TempData["state"] = new object();
        return RedirectToAction("Index");
    }
}
Darin Dimitrov
@Darin: When I refresh the page, I see that the default submit button is included in the Form variables. I'm new to this, but doesn't `Index(string back)` rely on the submit button not being part of the posted data?
Eric J.
What `Form` variables? The `back` parameter I've included could be used to detect which one of the two submit buttons have been pressed on the form (NEXT or PREV). You could have two submit buttons inside the same form and give them different names. For example: `<input type="submit" name="back" value="PREV" />`. Then you could check whether the `back` parameter is null or empty to know which of the two buttons was clicked.
Darin Dimitrov
@Darin: My two buttons are currently named Back and Next. When I click Refresh, Forms["Next"] contains a value.
Eric J.
Yes, then rename my `back` parameter to `Next` and don't look at `Forms["Next"]`, it will instead be passed to the controller action.
Darin Dimitrov
I'll give it a try... in the morning though as it's quite late here. Thanks for your help!
Eric J.
You are welcome, it's morning here :-)
Darin Dimitrov
@Darin: Good morning! After being redirected to Index() the Form[] collection is empty. Should I process in Index(string back) using this pattern?
Eric J.
@Eric, good evening to you :-) It is normal that after redirect the `Form[]` collection is empty because it contains only posted values. That's why I suggested you using the `TempData`. In the POST action store the values you need in the `TempData` (in my example I simply put an object but you could store any custom type you like) so that you can retrieve it later in the GET action after the redirect (after checking of course that the state is not null).
Darin Dimitrov