.NET Core / .NET 5 JSON 返回格式配置 踩坑日记

.NET Core / .NET 5 JSON 返回格式配置 踩坑日记

一般我们在项目中用到最多的JSON序列化工具,就是第三方的包 Newtonsoft.Json,说实话这个东西是真的香,香的不得了,但是我今天踩坑了。

JSON 返回格式全局配置

现在百度一个.NET Core / .NET 5 JSON 返回格式全局配置,好家伙多的一批,但是我不得不承认“CV大法”是真的被普遍了。
先粘贴一段,踩坑之前的代码。
在这里插入图片描述
熟悉吧,这段代码,对没错,这就是百度出来的很普遍的代码,但是你真的知道这段代码的意义嘛?
在这里插入图片描述
看这张图片,懂了吧,这段代码配置的不是 “Newtonsoft.Json” 第三方包的配置,而是.NET Core自带的一个JSON序列化工具的配置,与这个第三方包完全不沾边。

懂了吧~ 懂了吧~ 懂了吧~

踩坑还原

因为最近在研究VUE3 + TS + AXIOS 准备搭建一套前端的框架,或者说博客系统吧,所以我遇到坑了,这边前端的一些方法忽略,以后会说到。
在这里插入图片描述在这里插入图片描述
这是一张前端 AXIOS 封装的图片,本着职业原则,我在底层对HTTP请求进行了处理,如果这个请求成功了,这边成功的意思是连接到了API 接口,并且返回了数据,但是对于接口里面真正的操作是否真的成功了,我这边是根据 Success 状态去判断的。

先粘贴一下我后端通用的返回Dto 类
在这里插入图片描述
这个是我后端定义的通用返回Dto类

回归正文,在前端HTTP请求底层,我进行了返回结果操作是否成功进行了判断,如果成功,正常返回,如果失败,就会默认弹出失败信息。
但是当我第一次去尝试弹出失败信息的时候,却告诉我 “ResultInfo” 不存在??? What??? 怎么可能,我当时F12 进入 Network 一查看,我的发??? 为什么,我这边的 “ResultInfo” 首字母是大写的?我明明配置了首字母小写的配置啊,并且我正常返回的时候,都是小写的啊。
在这里插入图片描述
错误返回:
在这里插入图片描述
OK,我现在怀疑是我后端的问题了,因为我后端是做了全局异常处理的中间件的,并且我这边的所有操作错误,都是通过我自定义的一个异常类去抛出的,并且,异常信息还通过百度翻译进行翻译,在进行返回。懂了吧?? 好吧,没懂不要紧,这些操作后期会讲到。

直接粘贴我的异常处理中间件吧。

/// <summary>
/// 全局异常捕获中间件
/// </summary>
public class ExceptionHandlerMiddleware
{
    private static RequestDelegate requestDelegate;


    public ExceptionHandlerMiddleware(RequestDelegate requestDelegate)
    {
        ExceptionHandlerMiddleware.requestDelegate = requestDelegate;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        try
        {
            await requestDelegate(httpContext);
        }
        catch (Exception e)
        {
            await HandleExceptionAsync(httpContext, e);
        }
    }

    private static async Task HandleExceptionAsync(HttpContext httpContext, Exception e)
    {
        if (e == null)
            return;
        await WriteExceptionAsync(httpContext, e).ConfigureAwait(false);
    }

    private static async Task WriteExceptionAsync(HttpContext httpContext, Exception e)
    {
        var result = new ResultDto<string>();
        var message = string.Empty;
        try
        {
            switch (e)
            {
                case LearnCodeSystemException:
                    httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    Log4NetHelper.Error(e.Message, e);
                    break;
                case UnauthorizedAccessException:
                    httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    break;
                case LearnCodeException:
                    httpContext.Response.StatusCode = (int)HttpStatusCode.OK;
                    break;
                default:
                {
                    if (e != null)
                    {
                        httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    }

                    break;
                }
            }

            httpContext.Response.ContentType = "application/json";
            // 把异常信息通过百度翻译再返回出去
            var resultDto = await BaiDuTranslatorHelper.Translator(e?.GetBaseException().Message);
            // 由于Get请求可能出现Url过长,获取不到数据,所以采用Post请求再翻译一次
            if (resultDto?.Trans_Result == null)
            {
                resultDto = await BaiDuTranslatorHelper.TranslatorPost(e?.GetBaseException().Message);
            }

            // 判断是否出错
            if (resultDto?.Error_Code > 0)
            {
                throw new Exception(
                    $"BaiDu translation API Error. ErrorCode:{resultDto?.Error_Code} ErrorInfo:{resultDto?.Error_Msg}");
            }

            result.Success = false;
            result.ResultInfo =
                $"【{GlobalContext.ConfigInto.Startup.ApiName}】温馨提示:[{resultDto?.To}]:{resultDto?.Trans_Result[0].Dst} [{resultDto?.From}]:{resultDto?.Trans_Result[0].Src}";
            result.ResultStatusCode = (HttpResultStatusCodeEnum)httpContext.Response.StatusCode;
            message =
                $"[{resultDto?.To}]:{resultDto?.Trans_Result[0].Dst} [{resultDto?.From}]:{resultDto?.Trans_Result[0].Src}";
        }
        catch (Exception ex)
        {
            result.Success = false;
            result.ResultInfo =
                $"【{GlobalContext.ConfigInto.Startup.ApiName}】温馨提示:[en]:System Error.[zh]:系统错误。Info:{ex.Message}";
            result.ResultStatusCode = (HttpResultStatusCodeEnum)httpContext.Response.StatusCode;
            message = "[en]:System Error.[zh]:系统错误。";
        }
        finally
        {
            // 写入Error信息
            Log4NetHelper.Error(message, e);
            // 异常信息返回格式 [zh]:中文 [en]英文v
            await httpContext.Response.WriteAsync(JsonConvert.SerializeObject(result)).ConfigureAwait(false);
        }
    }
}

这个是我的抛出异常的地方,采用的自定义的一个异常处理类。
在这里插入图片描述
在这里插入图片描述
没错,正如你看到的,我这边确实使用了 第三方包 的JSON 序列化方法,对,没错,就是这里,序列化的时候并没有配置格式,所以,第三方的包默认把首字母大写了,直接返回给前端了。

所以,现在问题找到了,是不是很好解决了?

解决方案

现在问题找到了,我们就要解决问题了,OK,“面向百度变成,我搜索”。
好家伙,不搜索不知道,一搜索吓一跳。关键词“.NET Core 配置JSON 序列化格式”
在这里插入图片描述
查看了一下具体的解决方案,要么就是错误写法,要么就是 “CV大法” 过来的,标点符号都不带改的,一模一样,好家伙。
好吧,我承认百度没啥用了,然后我进行了 “Google”,找了半天,终于让我在某一个社区找到了这一段代码。
在这里插入图片描述
对,没错,这一段代码就是配置 “Newtonsoft.Json” 第三方库的JSON 序列化配置的全局处理。

OK,现在加上这段代码,我们再去前端请求一下接口。
漂亮,不管什么情况下都是小写开头了。
到此我们的问题就解决了!

为什么会出现这种情况?

至于为什么会出现这种情况,自我理解,只是自我理解,这里不接受反驳哈,哈哈哈哈。

首先,我们如果是正常请求,并且所有的判断都是通过的,没有进入异常处理中间件,OK,那么数据正常返回,众所周知,后端返回给前端数据的时候,会默认进行JSON格式化的,OK,那么这里就是用的.NET 自带的JSON 工具进行序列化的。那么到这里,我们的数据都是没有问题的,因为我一开始就配置了这个配置项。
然后,如果这个请求,在进行某些判断的时候,比如说非空验证啥的,就是抛出一个异常,进入我们的异常处理中间件,最后通过这个第三方的包进行序列化,然后写入HttpContext的 Response里面,到这里,我们的返回格式,就变成了首字母大写,如果没有配置的话。问题就是出现在这里。
所以我们在“Startup” 类的 “ConfigureServices” 方法中配置一些这个第三方包的全局格式,就解决了问题~

今天的学习就到这里吧!

你羡慕的生活都是你没熬过的苦。

You envy the life is you did not go through the bitter.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值