views:

591

answers:

5

In controller, try...catch can catch exception. How to catch exception in view? for example, a view may have code like:

<%= Html.Encode(Model.MyID)%>

If Model is null, you will get exception when access the view. where to catch the exception and redirect user to a error page with user-friendly error message?

+3  A: 

This logic should be handled inside your Controller and not the View. For example if you are trying to view a Product with MyID that does not exist then redirect to an error page.

If an error has occured you could also redirect to an InvalidProduct view that would provide a more detailed error description/instructions.

Edit: In addition to peoples comments below to catch unhandled exceptions add the [HandleError] attribute either on your ActionResult method declaration or on the Controller (for all ActionResults).

[HandleError]
public ProductsController
{
    public ActionResult Show(int id)
    {
        Product p = //e.g. get product from db

        if (p == null)
        {
            return RedirectToAction("Error");
            //return RedirectToAction("InvalidProduct");
        }

        return View(p);
    }
David Liddle
What happens if there's an exception/error that you don't know about?
mgroves
Your application should "fail fast". You can't handle an exception you don't know about anyway.
jlembke
A: 

Well, you can't always catch every error in the controller, but hopefully your views should be lightweight enough where it's very unlikely to happen.

However, if an exception does get thrown in the view, you should have a custom 500 error page set up to redirect the user to just in case. I believe you can set up a redirect like this in the Global.asax or it might be an IIS setting as well.

mgroves
+2  A: 

Simply add the [HandleError] attribute to the top of your Controller class. This way, any exception generated by your Controller will be handled and the user will be presented /Views/Shared/Error.aspx. The model passed to that view is a System.Web.Mvc.HandleErrorInfo object.

The controller:

[HandleError]
public class MyController : Controller
{
  public ActionResult Default()
  {
    MyClass thing = MyClassFactory.Create();
    return View(thing);
  }
}

This is a for "last resort" exception handling. David's answer is best for those cases you can think of ahead of time.

Peter J
+2  A: 

Consider using Elmah: http://code.google.com/p/elmah/

The Matt
A: 

Although I support David Liddle's answer ("This logic should be handled inside your Controller and not the View") I can also tell you that you should code defensively in general.

For example instead of

try
{
    Html.Encode(Model.MyID)
}
catch
{
    Response.Redirect("~/Error/500");
}

you should

if (Model == null)
{
    // ...
}
else
{
    //.....
}

(ofcourse, again, don't put view selection logic in a view)

Andrei Rinea