赞
踩
一般我们在项目中用到最多的JSON序列化工具,就是第三方的包 Newtonsoft.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.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。