2015-08-19 2 views
1

Я использую пользовательские ошибки (web.config) для отправки необработанных исключений в мой ErrorController.TempData пуст, когда установлен в блоке catch, и мы восстанавливаем

В моем основном контроллере я бросаю исключение, перехватываю его в блоке catch и устанавливаю TempData, чтобы иметь какое-то удобное сообщение. Затем я затем throw, который затем отправляется на адрес ErrorController.

Когда я проверяю TempData здесь, он пуст (как и Session, но это было бы, не так ли?).

Я уверен, что он не должен быть пустым, и это правильный способ отправки данных между контроллерами ... но он не работает! Я ошибаюсь в своем понимании?

HomeController:

catch (Exception ex) 
{ 
    TempData["MsgForUser"] = "useful message to show"; 
    // Do some logging... 

    throw; 
} 

ErrorController:

public ActionResult DisplayError(int id) 
{ 
    ViewBag.MsgForUser = TempData["MsgForUser"]; 
    return View(); 
} 

Web.config:

<system.web> 
    <customErrors mode="On" defaultRedirect="~/ErrorPage/DisplayError"> 
    <error redirect="~/Error/DisplayError/403" statusCode="403" /> 
    <error redirect="~/Error/DisplayError/404" statusCode="404" /> 
    <error redirect="~/Error/DisplayError/500" statusCode="500" /> 
    </customErrors> 
+0

@ScottWeldon Его просто мои предпочтения, но заголовки из кода (ErrorController, Web.config) Безразлично «нужно быть внутри кодового блока, он просто выглядит немного, но странно. – jmattheis

ответ

1

Я обнаружил, что сессия была уничтожена при выполнении throw в блоке верхнего уровня catch, поскольку запрос на контроллер ошибок. Однако я обнаружил, что возвращающийся RedirectToAction() сохранил его.

Итак, я создал свой собственный тип исключения:

public class MyApplicationException : Exception 
{ 
    /// <summary> 
    /// A message that can be shown to the user i.e. not technical 
    /// </summary> 
    public string MessageForUser { get; set; } 

    public MyApplicationException() 
    { 
    } 

    public MyApplicationException(string message, string messageForUser="") 
     : base(message) 
    { 
     MessageForUser = messageForUser; 
    } 

    public MyApplicationException(string message, Exception inner, string messageForUser = "") 
     : base(message, inner) 
    { 
     MessageForUser = messageForUser; 
    } 
} 

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

if (MyList.Count > 14) 
{ 
     throw new MyApplicationException("More than 14 records received: " + MyList.Count.ToString(), "There is a maximum limit of 14 records that can be processed at a time. Please call us to discuss your requirement to process in greater quantities."); 
} 

и при ловле его я выбираю сообщение для пользователя, журнал ошибок, и return RedirectToAction(), чтобы перейти на страницу с ошибкой, не теряя TempData.

catch (MyApplicationException myAppEx) 
{ 
    // If there is a user-friendly message then store it for DisplayError to show 
    if (String.IsNullOrEmpty(myAppEx.MessageForUser) == false) 
    { 
     TempData["MsgForUser"] = myAppEx.MessageForUser; 
    } 

    // Do some logging to elmah or a custom logger 
    util.LogError(myAppEx, "MyFunc() threw an exception", args); 

    // 
    // We cannot throw here because we lose the Session & TempData. we have to do a manual redirect. 
    // 
    return RedirectToAction("DisplayError", "ErrorPage", new { id = 500 }); 
} 

и, наконец, на мой взгляд, я смотрю на него, и дисплей, если он существует:

<p> 
    An error occurred. Please check & try again later. 
</p> 
@if (String.IsNullOrEmpty(ViewBag.MsgForUser) == false) 
{ 
    <p class="more-info">Details: @ViewBag.MsgForUser</p> 
} 
0

TempData Стабильный метод при использовании RedirectToAction(), в обработки исключений делает ASP.net использовать эту функцию метод? возможно, нет !! Почему вы не используете Exception.Message, чтобы установить удобное для пользователя сообщение? установите ex.Message на свой блок catch, затем на вашем представлении с ошибкой вы можете получить к нему доступ. ваша модель просмотра ошибок должна быть @model HandleErrorInfo, а @Model.Exception.Message - ваше сообщение было установлено!

+0

Когда я «бросаю», он перенаправляется на контроллер Error (см. Выше код web.config). Между двумя контроллерами нет объекта исключения. – VictorySaber

+0

см. Lab29 в этом http://www.codeproject.com/Articles/1002109/Learn-MVC-Project-in-days-Day-6, может быть, полезный – Elyana

+0

вы rigth, мое решение отличается! – Elyana

Смежные вопросы