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?
使用c#Web Api 2,我有抛出InvalidOperationException的代码。返回状态代码302时,如何使用HandleException批注为重定向提供位置?
[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.
编辑:对不起,我有点急忙问这个问题。上面的类使用HandleExceptionAttribute类,该类继承自ExceptionFilterAttribute。当我试图调试他们的单元测试时,我没有意识到这一点。单元测试中不会出现此问题,但使用需要重定向URL的Visual Studio .webtest会显示该问题。从ExceptionFilterAttribute继承的类未提供允许提供重定向URL的参数。对不起,问题不完整,谢谢你花时间回答。
/// <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
{
2 个解决方案
#1
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.
编辑:感谢您更新了问题。虽然我仍然不确定你为什么要在这个WebApi方法中重定向。希望这个答案可以提供帮助。
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):
我将处理HandleExceptionAttribute中的所有异常逻辑。您甚至可以使用您正在寻找的302代码从那里重定向。你的HandleExceptionAttribute看起来像这样(我已经包含了3种基于异常返回结果的方法):
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) :
但是,如果您真的想按照您的要求完成它,可以在GetHandleException方法中添加第二个参数。这将接收消息字符串(或URL),然后在HandleExceptionAttribute中将重定向url添加到参数(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:
然后你的HandleExceptionAttribute看起来像这样:
public sealed class HandleExceptionAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
context.ActionContext.ActionArguments["message"] = "your redirect URL";
}
}
#2
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
虽然我没有看到在重定向到可视页面时有内容的意义。但我们去了
#1
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.
编辑:感谢您更新了问题。虽然我仍然不确定你为什么要在这个WebApi方法中重定向。希望这个答案可以提供帮助。
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):
我将处理HandleExceptionAttribute中的所有异常逻辑。您甚至可以使用您正在寻找的302代码从那里重定向。你的HandleExceptionAttribute看起来像这样(我已经包含了3种基于异常返回结果的方法):
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) :
但是,如果您真的想按照您的要求完成它,可以在GetHandleException方法中添加第二个参数。这将接收消息字符串(或URL),然后在HandleExceptionAttribute中将重定向url添加到参数(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:
然后你的HandleExceptionAttribute看起来像这样:
public sealed class HandleExceptionAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
context.ActionContext.ActionArguments["message"] = "your redirect URL";
}
}
#2
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
虽然我没有看到在重定向到可视页面时有内容的意义。但我们去了