首页 新闻 赞助 找找看

.NET异常处理和状态码问题,大家是怎么处理的

0
[已解决问题] 解决于 2019-01-30 15:09

起因是我想写一个RESTful风格的接口,比如添加一个学生实体,其中有一个字段Sex是int型,合法数据有1,和2,分别代表男和女。

现在,我想验证用户传过来的参数是否合法,如果不是1或者2,就抛出异常:

......
if(s.Sex!=1 | s.Sex!=2)
{
    throw new ArgumentException("sex参数异常");
}
......

但是我发现,这样throw出去的http状态码是200,和接口正常返回时的状态码相同,没法区分。

想请问下大家:

1. 是不是所有这样throw出来的exception的状态码都是200?

2. 有没有办法自己定义状态码?

3. 如果自定义自己的异常类(继承System.Exception),是否有必要?

4. 大家在写RESTful风格的接口时,是怎么处理异常的?

 

谢谢

在7楼的主页 在7楼 | 初学一级 | 园豆:151
提问于:2018-08-30 17:01
< >
分享
最佳答案
0

怎么会是 200 ?是不是被你在那个地方 catch 了?

奖励园豆:5
dudu | 高人七级 |园豆:31075 | 2018-08-30 17:05

我写了一个全局异常处理的中间件,在中间件里catch了:

    /// <summary>
    /// 全局异常过滤
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public async Task Invoke(HttpContext context)
    {
        int statusCode;
        string msg = "";
        try
        {
            await _next(context);
        }
        catch (Exception ex) //发生异常
        {
            statusCode = context.Response.StatusCode;
            //if (ex is ArgumentException) //如果是参数异常,将状态码赋值为400
            //{
            //    context.Response.StatusCode = 400;
            //    statusCode = 400;
            //}
            LogHelper.SetLog(LogLevel.Error, ex);
            await HandleExceptionAsync(context, statusCode, ex.Message);
        }
        finally
        {
            statusCode = context.Response.StatusCode;
            switch (statusCode)
            {
                case 401:
                    msg = "未授权";
                    break;
                case 404:
                    msg = "未找到服务";
                    break;
                case 502:
                    msg = "请求错误";
                    break;
                default:
                    if (statusCode != 200)
                    {
                        msg = "未知错误";
                    }
                    break;
            }
            if (!string.IsNullOrWhiteSpace(msg))
            {
                await HandleExceptionAsync(context, statusCode, msg);
            }
        }
    }
    /// <summary>
    /// 返回异常消息
    /// </summary>
    /// <param name="context"></param>
    /// <param name="statusCode"></param>
    /// <param name="msg"></param>
    /// <returns></returns>
    private static Task HandleExceptionAsync(HttpContext context, int statusCode, string msg)
    {
        var data = new { Code = statusCode.ToString(), Success = false, Msg = msg };
        context.Response.ContentType = "application/json;charset=utf-8";
        return context.Response.WriteAsync(JsonConvert.SerializeObject(data));
    }

是因为这个地方catch了才变成200的吗?

在7楼 | 园豆:151 (初学一级) | 2018-08-30 17:11

@在7楼: catch中处理完毕后需要把异常继续扔出去

try
{
    await _next(context);
}
catch (Exception ex) 
{
    //..
    throw ex;
}
dudu | 园豆:31075 (高人七级) | 2018-08-30 17:15

@dudu:
我想用这个全局异常处理中间件把异常处理了之后返回出去,比如如果是没有认证,就返401状态码和相应的response body(body的内容在第二个函数定义了)。
如果在catch里throw出去,就直接throw给前端了,不管什么异常,最后状态码都变500了。

在7楼 | 园豆:151 (初学一级) | 2018-08-30 17:37

@在7楼: 根据状态码判断是否出错,然后从响应内容中获取具体的错误信息

dudu | 园豆:31075 (高人七级) | 2018-08-30 17:56

@在7楼: 这里只需要将状态码设置为500,不需要继续抛异常

dudu | 园豆:31075 (高人七级) | 2018-08-30 20:25
其他回答(1)
0

可以直接return badrequest啊

吴瑞祥 | 园豆:29449 (高人七级) | 2018-08-30 18:13

写在控制器里,还是中间件?

支持(0) 反对(0) 在7楼 | 园豆:151 (初学一级) | 2018-08-30 18:20
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册