Ответ 1
Я придумал свое решение, добавив еще один фильтр.
public class PreserveViewDataOnExceptionFilter : IExceptionFilter
{
public void
OnException(ExceptionContext filterContext)
{
// copy view data contents from controller to result view
ViewResult viewResult = filterContext.Result as ViewResult;
if ( viewResult != null )
{
foreach ( var value in filterContext.Controller.ViewData )
{
if ( ! viewResult.ViewData.ContainsKey(value.Key) )
{
viewResult.ViewData[value.Key] = value.Value;
}
}
}
}
public static void
Register()
{
FilterProviders.Providers.Add(new FilterProvider());
}
private class FilterProvider : IFilterProvider
{
public IEnumerable<Filter>
GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
// attach filter as "first" for all controllers / actions; note: exception filters run in reverse order
// so this really causes the filter to be the last filter to execute
yield return new Filter(new PreserveViewDataOnExceptionFilter(), FilterScope.First, null);
}
}
}
Этот фильтр необходимо подключить глобально в методе Global.asax.cs Application_Start()
, вызвав PreserveViewDataOnExceptionFilter.Register()
.
Что я здесь сделал, это настроить новый фильтр исключений, который выполняется последним, после запуска фильтра HandleErrorAttribute, и копирует содержимое коллекции ViewData, которое было доступно контроллеру, который выбросил исключение в результат, созданный фильтр HandleErrorAttribute.