views:

338

answers:

3

I have used response.redirect in classic ASP and ASP.NET webforms. However, with MVC 2.0, I am running into something peculiar.

I have a private method in a controller class that is used by multiple controller methods to help load and validate some information. This private method is setup to redirect if a problem is discovered to a generic error message page.

The big problem I am noticing is that the calling controller class and page view attempt to complete rendering and loading before the redirect actually takes place. This is annoying in development because the View throws exceptions that I need to ignore before my generic error page finally loads.

As mentioned above, I am used to the older model of response.redirect which prevented subsequent code on a page from being executed as the new page would then load.

Any help or advice on redirects in MVC would be greatly appreciated.

+7  A: 

In ASP.NET MVC, you would normally redirect to another page by returning a RedirectResult from the controller method.

Example:

public ActionResult Details(int id)
{
     // Attempt to get record from database
     var details = dataContext.GetDetails(id);

     // Does requested record exist?
     if (details == null)
     {
         // Does not exist - display index so user can choose
         return RedirectToAction("Index");
     }

     // Display details as usual
     return View(details);
}
Robert Harvey
Great answer. Thanks for the help!
Swoop
A: 

Have you tried specifying the EndResponse parameter for Response.Redirect?

Response.Redirect(errorPage, true)

http://msdn.microsoft.com/en-us/library/a8wa7sdt(VS.80).aspx

AaronSieb
I messed with the EndResponse parameter some, and felt like I was getting very odd results. Setting it to true seemed to have no effect, while false caused the page to stop execution on the nullreference errors in my View page.
Swoop
+2  A: 

The conventional mechanism to redirect in ASP.Net MVC is to return an object of type RedirectResult to the client. If this is done before your View method is called, your view methods will never be called.

If you call Response.Redirect yourself, instead of letting Asp.Net MVC's front controller do that for you, your controller method will continue on until it finishes or throw an exception.

The idiomatic solution for your problem is to have your private method return a result that your controller can use.

for example:

public ActionResult Edit(MyEntity entity)
{
  if (!IsValid()) return Redirect("/oops/");
  ...
  return View();

}

private bool IsValid()
{
  if (nozzle==NozzleState.Closed) return false;
  if (!hoseAttached) return false;
  return (userRole==Role.Gardener);
}
JasonTrue
This explains what I was seeing, and is a great solution. Thanks for the help!
Swoop