2

I wrote my own HandleError attribute.

When an error occurs during an ajax request I want to return a partialview and when the request is non ajax a view with master page should be returned.

So far I wrote this

     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class IcpHandleErrorAttribute : FilterAttribute, IExceptionFilter
{
    private readonly Type _exceptionType = typeof(Exception);

    public IcpHandleErrorAttribute()
    {} 

    public void OnException(ExceptionContext filterContext)
    {
        if (filterContext == null)throw new ArgumentNullException("filterContext");

        if (filterContext.IsChildAction)return;

        if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)return;

        Exception exception = filterContext.Exception;

        if (new HttpException(null, exception).GetHttpCode() != 500)return;

        if (!_exceptionType.IsInstanceOfType(exception))return;

        var controllerName = (string)filterContext.RouteData.Values["controller"];
        var actionName = (string)filterContext.RouteData.Values["action"];

        var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);

        ViewResultBase result;

        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            result = new PartialViewResult { ViewName = "ErrorAjax" };
        }
        else
        {
            result = new ViewResult{ViewName = "Error"}; 
        }

        result.ViewData = new ViewDataDictionary<HandleErrorInfo>(model);
        result.TempData = filterContext.Controller.TempData;

        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();
        filterContext.HttpContext.Response.StatusCode = 500;

        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    }
}

But the masterpage is returned even when the PartialViewResult is assigned to the result. Why is this happening ?

The ErrorAjax partial view

@model HandleErrorInfo

@{
    Layout = null;
}

<div class="error">@Model.Exception.Message</div>

The action is called through jquery's post.

The action method is a test case

[HttpPost]
public ActionResult Create(ProjectCreateCommand command)
{
    throw new NotImplementedException("ajax");

    return Post(command);
}

The attribte registration in global.asax 's Application_Start() method.

    GlobalFilters.Filters.Add(new IcpHandleErrorAttribute());

    RegisterGlobalFilters(GlobalFilters.Filters);
user49126
  • 1,825
  • 7
  • 30
  • 53

2 Answers2

1

You don't seem to be doing anything useful with your result local variable like for example assigning it to the filter context:

filterContext.Result = result;
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Yes this missing part was crucial :-) But anyway it doesn't work. The master page is returned with the partial view. – user49126 Jan 26 '12 at 12:33
  • @user49126, could you provide more code? How are you calling the action from the client? What error does the action throws? How did you register your custom attribute? – Darin Dimitrov Jan 26 '12 at 12:34
  • 1
    @user49126, in the info you've added I cannot see anywhere how are you calling the action method from client code. Also how does your `RegisterGlobalFilters` method look like? Is there still a call to the standard HandleErrorAttribute which might conflict with your custom attribute? – Darin Dimitrov Jan 26 '12 at 13:11
  • Bingo!! There was call to the standart HandleErrorAttribute in the RegisterGlobalFilters method.I totally forgot about it. – user49126 Jan 26 '12 at 13:37
0

If this not Ajax request you need redirect to some Action. And in this action return View()

Oleksandr Fentsyk
  • 5,256
  • 5
  • 34
  • 41