7

Using c# Web Api 2, I have code that throws an InvalidOperationException. When returning a status code of 302, how do provide a location for the redirect using the HandleException annotation?

[HandleException(typeof(InvalidOperationException), HttpStatusCode.Found, ResponseContent = "Custom message 12")]
public IHttpActionResult GetHandleException(int num)
{
     switch (num)
     {
          case 12: throw new InvalidOperationException("DONT SHOW invalid operation exception");

          default: throw new Exception("base exception");
     }
}

Edit: Sorry, I asked this question in a bit of haste. The above class uses a HandleExceptionAttribute class which inherits from ExceptionFilterAttribute. I didn't realize this at the time I was trying to debug their unit test. The problem doesn't arise in a unit test, but does show up using a Visual Studio .webtest that requires the redirect url. The class that inherits from ExceptionFilterAttribute did not provide a parameter that allows for the redirected URL to be supplied. Sorry for an incomplete question and thanks for taking time to answer.

/// <summary>
   /// This attribute will handle exceptions thrown by an action method in a consistent way
   /// by mapping an exception type to the desired HTTP status code in the response.
   /// It may be applied multiple times to the same method.
   /// </summary>
   [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
   public sealed class HandleExceptionAttribute : ExceptionFilterAttribute
   {
TheEmirOfGroofunkistan
  • 5,476
  • 8
  • 37
  • 53

2 Answers2

3

Edited: Thanks for updated the question. Although I'm still not exactly sure why you would want to redirect in this WebApi method. Hopefully this answer can help though.

I would handle all the exception logic in the HandleExceptionAttribute. You could even redirect from there with the 302 code you are seeking. Your HandleExceptionAttribute would look like this(I've included 3 different ways of returning a result based on an exception):

public sealed class HandleExceptionAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        //TODO: we can handle all types of exceptions here. Out of memory, divide by zero, etc etc.
        if (context.Exception is InvalidOperationException)
        {
            var httpResponseMessage = context.Request.CreateResponse(HttpStatusCode.Redirect);
            httpResponseMessage.Headers.Location = new Uri("http://www.YourRedirectUrl");
            throw new HttpResponseException(httpResponseMessage);
        }
        if (context.Exception is UnauthorizedAccessException)
        {
            context.Response = context.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, context.Exception.Message);
            return;
        }
        if (context.Exception is TimeoutException)
        {
            throw new HttpResponseException(context.Request.CreateResponse(HttpStatusCode.RequestTimeout, context.Exception.Message));
        }

        context.Response = context.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Unable to process your request.");
    }
}

However if you really want it done the way you ask, you could add a second parameter to your GetHandleException method. This would take in a message string(or URL) then in your HandleExceptionAttribute you would add the redirect url to the parameter(ActionArguements) :

public IHttpActionResult GetHandleException(int num, string message = "")
{
    switch (num)
    {
        case 12: return Redirect(message); //message string would be your url

        default: throw new Exception("base exception");
    }
}

Then your HandleExceptionAttribute looks like this:

public sealed class HandleExceptionAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        context.ActionContext.ActionArguments["message"] = "your redirect URL";

    }
}
Andrew M.
  • 382
  • 3
  • 11
  • 1
    User wants to redirect to specific pages based on exception. – jitendra singh Feb 28 '16 at 17:36
  • 1
    The question is a bit confusing. Are you trying to just throw the exception? If so, how about you create a custom exception on your own with extra data on it like the location you want to redirect to? – drunkcoder Feb 29 '16 at 09:38
  • @TheEmirOfGroofunkistan I've updated my answer based on your updated question. – Andrew M. Mar 01 '16 at 16:09
0

Improvise from the following

 public class HandleExceptionAttribute : ExceptionFilterAttribute
{
    public Type ExceptionType { get; set; }

    public HandleExceptionAttribute(Type exceptionType)
    {
        ExceptionType = exceptionType;
    }
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Exception.GetType()==ExceptionType)
        {
            var response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.Moved);
            response.Headers.Location=new Uri("http://google.co.uk");
            response.Content=new StringContent("Message");
            actionExecutedContext.Response = response;
        }
        base.OnException(actionExecutedContext);
    }
}

Usage

[HandleException(typeof(ExceptionOfTypeA))]
    public HttpResponseMessage Get(int id)
    {
        throw new ExceptionOfTypeA();
    }

Although i dont see the point of having content in there when this is redirect to a visual page. but there we go

Gurpreet
  • 1,382
  • 11
  • 24