Обработчик исключений дочерних действий

У меня есть простой контроллер:

public class RedirectController : Controller {
    public ActionResult Index() {
        return View();
    }

    [ChildActionOnly]
    public ActionResult Child1() {
        return View();
    }


    [ChildActionOnly]
    public ActionResult Child2() {
        return View();
    }

[ChildActionOnly]
    public ActionResult Child3() {
        throw new Exception("abc");        
    }
}

Index.cshtml

...
@Html.Action("Child1")
...

Child1.cshtml

...
@Html.Action("Child2")
...

Child2.cshtml

...
@Html.Action("Child3")
...

Child3 сгенерирует исключение и сгенерирует новое исключение ("abc"). По какой-то причине я установил макет для error.cshtml, после чего содержимое экспорта, наконец, содержит Index.cshtml, Child1.cshtml, Child2.cshtml и Error.cshtml.

Поэтому я определил пользовательский ExceptionFilter для обработки этого исключения

public class MyExceptionAttribute : ActionFilterAttribute , IExceptionFilter {

    public void OnException(ExceptionContext filterContext) {
    ...
        ...
        if(filterContext.ParentActionViewContext != null) {
    //remove parent actions' exported contents
            ViewContext par = filterContext.ParentActionViewContext;
            while(null != par){
                var wtr = (StringWriter)par.Writer;
                wtr.GetStringBuilder().Clear();
                par = par.ParentActionViewContext;
            }

        }
...
...

После выполнения этого фильтра окончательный вывод html удалил содержимое "Index", "Child1" и "Child2", но содержимое "Layout" все еще выдавалось.

<html>
    ...(Layout content)
    <html>
    ...(Error.cshtml content)
    </html>
</html>

Есть ли способ удалить все содержимое, кроме содержимого ошибки?

1 ответ

У меня есть решение:

Когда дочернее действие генерирует исключение, пользовательский ExceptionFilter обрабатывает его и удаляет вывод всех родительских действий, кроме макета.

Итак, в _ViewStart.cshtml:

@{
if(!this.ViewContext.IsChildAction) {
    Layout = "~/Views/Shared/_Layout.cshtml";
}
}
Другие вопросы по тегам