Вопрос по .net, asp.net-mvc – как отловить исключение вида MVC?

11

В контроллере попробуйте ... catch может поймать исключение. Как поймать исключение на виду? например, представление может иметь такой код:

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

Если Model имеет значение null, вы получите исключение при доступе к представлению. где перехватить исключение и перенаправить пользователя на страницу с сообщением об ошибке?

Какие технологии вы используете? John Topley
Вот решение для представлений модуля Orchard:stackoverflow.com/a/29536117/3936440 ViRuSTriNiTy
Я бы не использовал исключения для неисключительного поведения и определенно не в представлении. Paco
MS ASP.NET MVC Framework KentZhou

Ваш Ответ

7   ответов
2

Эта логика должна обрабатываться в вашем контроллере, а не в представлении. Например, если вы пытаетесь просмотреть Продукт с MyID, который не существует, перенаправьте на страницу с ошибкой.

Если произошла ошибка, вы также можете перенаправить на представление InvalidProduct, которое предоставит более подробное описание ошибки / инструкции.

Редактировать: в дополнение к комментариям людей ниже, чтобы перехватить необработанные исключения, добавьте атрибут [HandleError] либо в объявлении метода ActionResult, либо в Controller (для всех 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);
    }
Что произойдет, если возникнет исключение / ошибка, о которой вы не знаете?
Ваша заявка должна быть «провалена быстро». Вы все равно не можете обработать исключение, о котором не знаете.
Это не ответ на вопрос ФП. Конечно, лучше иметь такую логику в контроллере, но это все еще не ответ. Я работаю над локальным прототипом на клиенте, где загрузка файлов занимает около 15 минут. Виды можно редактировать в Блокноте, но для редактирования контроллера мне нужно перекомпилировать на своем компьютере и загрузить двоичные файлы. Так что я использую представления, чтобы опробовать вещи. Но я не вижу исключений, поскольку они скрыты некоторым прокси-сервером между мной и сервером, и они не отображаются в журналах. Все еще ищу решение.
2

Хотя я поддерживаю ответ Дэвида Лиддла («Эта логика должна обрабатываться в вашем контроллере, а не в представлении»), я также могу сказать вам, что вы должны защищать код в целом.

Например, вместо

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

вам следует

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

(разумеется, опять же, не помещайте логику выбора представления в представление)

я должен добавить@ доif а такжеelse?
4

Просто добавьте атрибут [HandleError] в начало вашего класса Controller. Таким образом, любое исключение, сгенерированное вашим контроллером, будет обработано, и пользователю будет представлен файл /Views/Shared/Error.aspx. Модель, переданная этому представлению, является объектом System.Web.Mvc.HandleErrorInfo.

Контроллер:

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

Это для "последней инстанции" Обработка исключений. Ответ Дэвида лучше всего подходит для тех случаев, о которых вы можете подумать заранее.

2

Рассмотрите возможность использования Elmah:http://code.google.com/p/elmah/

1

Я согласен с Мэттью Гроувсом в том, что вы не всегда можете уловить каждую ошибку. К сожалению, в моем случае, у меня есть точка зрения, которая имеет 100 переменных. Трудно объяснить их все.

Здесь есть множество способов отловить ошибки:http://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET-MVC-methods-explaine

В моем случае я хотел записать ошибку, которая произошла в представлении, с данными, которые использовались в контроллере. Поэтому я решил переопределить OnException в моем контроллере. Таким образом, во время действия я могу сохранить свои данные на экземпляре контроллера, а затем получить доступ к ним позже в методе OnException.

2

Вы можете использовать try / catch в блоке скрипта в представлении:

@try
{    
  <div>typical Razor view stuff here...</div>
}
catch (Exception ex)
{
  @<script type="text/javascript">
    alert('@ex.Message.Replace("'","\\'").Replace("\r\n","<br/>")');
  </script>
}
Благодарю. Это действительно помогло нам быстро решить производственную проблему. То, что я изменил в вашем коде, - это сделать console.log вместо alert, и я записал весь & quot; ex & quot; объект как JSON, так что я могу просматривать все внутренние объекты "ex". Ниже приведено то, что я использовал в своем сценарии: console.log («@ Newtonsoft.J, son.JsonConvert.SerializeObject (ex)»);
1

Ну, вы не всегда можете отследить каждую ошибку в контроллере, но, надеюсь, ваши представления должны быть достаточно легкими, где это вряд ли произойдет.

Однако, если исключение действительно генерируется в представлении, у вас должна быть настроена настраиваемая страница ошибки 500, чтобы перенаправить пользователя на всякий случай. Я полагаю, что вы можете настроить перенаправление, подобное этому, в Global.asax или это может быть также настройка IIS.

Похожие вопросы