asp.net core 自定义 Content-Type

asp.net core 实现支持自定义 Content-Type

Intro

我们最近有一个原本是内网的服务要上公网,在公网上有一层 Cloudflare 作为网站的公网流量提供者,CloudFlare 会有一层防火墙拦截掉一些非法的请求,我们有一些 API 会提交一些 html 内容,经过 Cloudflare 的时候会被 Cloudflare 拦截,导致某些功能不能够正常使用,于是就想对提交的数据进行一个编码之后再提交,服务器端针对需要解码的请求进行解码再解析,我们新加了一个 Content-Type 的支持,编码后的数据使用新的 Content-Type,对于不编码的数据依然可以工作,目前我们做了一个简单的 base64 编码,如果需要的话也可以实现复杂一些的加密、压缩等。

Basis

asp.net core 默认支持 JSON 请求,因为内置了针对 JSON 内容的 Formatter,.NET Core 2.x 使用的是 Newtonsoft.Json 作为默认 JSON formatter,从 .NET Core 3.0 开始引入了 System.Text.Json 作为默认的 JSON formatter,如果要支持 XML 需要引入针对 XML 的 formatter,相应的如果需要增加其他类型的请求实现自己的 formatter 就可以了

Formatter 分为 InputFormatterOutputFormatter

  • InputFormatter 用来解析请求 Body 的数据,将请求参数映射到强类型的 model,Request Body => Value

  • OutputFormatter 用来将强类型的数据序列化成响应输出,Value => Response Body

Formatter 需要指定支持的 MediaType,可以理解为请求类型,体现在请求头上,对于 InputFormatter 对应的就是  Content-Type ,对于 OutputFormatter 对应的是 Accept,asp.net core 会根据请求信息来选择注册的 formatter。

Sample

先来看一下实现效果吧,实现效果如下:

swagger

swagger 的支持也算比较好了,在增加了新的 Content-Type 支持之后在 swagger 上可以看得到,而且可以切换请求的 Content-Type,上图中的 text/base64-json 就是我自定义的一个 Content-Type

默认请求:

json-request

对原始请求进行 base64 编码,再请求:

base64-json-request

Implement

实现代码如下:

public class Base64EncodedJsonInputFormatter : TextInputFormatter
{public Base64EncodedJsonInputFormatter(){// 注册支持的 Content-TypeSupportedMediaTypes.Add("text/base64-json");SupportedEncodings.Add(Encoding.UTF8);}public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding){try{using var reader = context.ReaderFactory(context.HttpContext.Request.Body, encoding);var rawContent = await reader.ReadToEndAsync();if (string.IsNullOrEmpty(rawContent)){return await InputFormatterResult.NoValueAsync();}var bytes = Convert.FromBase64String(rawContent);var services = context.HttpContext.RequestServices;var modelValue = await GetModelValue(services, bytes);return await InputFormatterResult.SuccessAsync(modelValue);async ValueTask<object> GetModelValue(IServiceProvider serviceProvider, byte[] stringBytes){var newtonJsonOption = serviceProvider.GetService<IOptions<MvcNewtonsoftJsonOptions>>()?.Value;if (newtonJsonOption is null){await using var stream = new MemoryStream(stringBytes);var result = await System.Text.Json.JsonSerializer.DeserializeAsync(stream, context.ModelType,services.GetRequiredService<IOptions<JsonOptions>>().Value.JsonSerializerOptions);return result;}var stringContent = encoding.GetString(bytes);return Newtonsoft.Json.JsonConvert.DeserializeObject(stringContent, context.ModelType, newtonJsonOption.SerializerSettings);}}catch (Exception e){context.ModelState.TryAddModelError(string.Empty, e.Message);return await InputFormatterResult.FailureAsync();}}
}

上述代码兼容了使用 System.Text.JsonNewtonsoft.Json,在发生异常时将错误信息添加一个 ModelError 以便在前端可以得到错误信息的反馈,例如传一个不合法的 base64 字符串就会像下面这样:

error

实际使用的时候,只需要在 Startup 里配置一下就可以了,如:

services.AddControllers(options =>{options.InputFormatters.Add(new Base64EncodedJsonInputFormatter());});

More

通过自定义 Content-Type 的支持我们可以无侵入的实现不同的请求内容,上面的示例代码可以在 Github 上获取 https://github.com/WeihanLi/SamplesInPractice/tree/master/AspNetCoreSample,可以根据自己的需要进行自定义

References

  • https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/custom-formatters?view=aspnetcore-5.0

  • https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/web-api/advanced/custom-formatters/samples

  • https://github.com/WeihanLi/SamplesInPractice/tree/master/AspNetCoreSample

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304017.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何优雅的移植JavaScript组件到Blazor

Blazor作为一个新兴的交互式 Web UI 的框架&#xff0c;有其自身的优缺点&#xff0c;如果现有的 JavaScript 组件能移植到 Blazor&#xff0c;无疑让 Blazor 如虎添翼&#xff0c;本文就介绍一下自己在开发 BulmaRazor 组件库的时&#xff0c;封装现有的 JavaScript 组件的方法…

把握人工智能命脉的有效方法

最近广州的天气老是变幻无常&#xff0c;往往今天还热得要命第二天就寒风瑟瑟&#xff08;如下图&#xff09;&#xff0c;让小天甚是怀念每天艳阳高照的夏天&#xff0c;虽然热了点但好歹不用担心猝不及防地收到寒风暴雨黄色预警。说到夏天&#xff0c;不得不提一下1956年的那…

微软的焦虑?想多了!从.NET6 Preview2到大厂招聘,起飞

看了篇文章叫《从.NET看微软的焦虑》&#xff0c;这里忍不住先吐槽一下&#xff0c;看完不仅毫无收获&#xff0c;而且有一种先起个夺眼球的标题&#xff0c;然后再东拼西凑找证据。讲真的&#xff0c;微软市值基本上等于“阿里腾讯百度”三者之和&#xff0c;居然还焦虑的无法…

TED演讲:区块链将如何改变世界?看完太震撼了!

区块链是什么&#xff1f;如果你不知道&#xff0c;你应该了解&#xff1b;如果你知道&#xff0c;有可能你仍需要了解一些它工作原理。唐泰普斯科特在此使这改变世界、建立信任的科技变得简明易懂。他表示&#xff0c;这就是第二代互联网&#xff0c;将有可能改变我们的金钱、…

re管理器Java_自定义布局管理器-FormLayout

第二部分&#xff1a;自定义布局管理器在java.awt包与javax.swing包下有许多现成的布局类&#xff0c;比如BorderLayout、FlowLayout&#xff0c;还有较为复杂的、用于精确定位的布局类GridBagLayout、SpringLayout等。起初我刚刚从事gooey时(06年中)&#xff0c;企图依靠JDK自…

如何看待 70% 的程序员,缺乏数据结构和算法知识?

金三银四来了&#xff0c;各大厂动静不小&#xff0c;都在储备人才&#xff0c;绝对是程序员面试的黄金时间了&#xff0c;不少同学也在后台反馈面试中遇到的一些问题&#xff0c;所以今天想跟大家说说算法。说起算法&#xff0c;那大厂面试是绝对必考的&#xff0c;可以说是一…

Sorry,关注这些 IT 技术类公众号,真的可以为所欲为

工作和生活节奏超快的今天&#xff0c;想要不断提升自我&#xff0c;碎片化阅读学习是你最佳的选择&#xff0c;如果你已经有了一颗学习的心&#xff0c;却苦于不知道从哪里学习&#xff0c;那么&#xff0c;这些学习的工具和途径就很重要了。今天为你推荐一些 IT技术领域的微信…

数据告诉你,抖音是如何在半年之内逆袭的

从春节至今&#xff0c;音乐短视频社区“抖音”在苹果应用商店免费排行榜上连续多天霸榜。凭借多元的音乐风格、酷炫的视觉编辑功能、个性化的分发机制以及良好的社区氛围&#xff0c;抖音在上线不久后便受到了年轻用户的追捧。在这一年半的时间里&#xff0c;抖音到底成长到了…

非名校出身的我,是如何拿到Facebook、谷歌、微软、亚马逊和Twitter的Offer的?

非名校出身&#xff0c;也没有知名科技公司的工作经验&#xff0c;他竟同时拿到了美国5家顶尖科技公司的Offer。他究竟是如何做到的&#xff1f;这篇文章是专门为那些即将开始找工作的人写的。很多正在找工作的人可能会担心因为自己不是毕业于常青藤名校而无法在顶尖科技公司找…

GitLab 服务器的迁移以及注意点

Git 已经是代码托管工具中的主流了&#xff0c;如果是自己搭建私有的 Git 服务器我们一般会使用 GitLab &#xff0c;在《在CentOS7中安装GitLab》 一文中有介绍怎样在 CentOS7 中安装 GitLab 。文本主要介绍怎样迁移 GtiLab 。环境CentOS&#xff1a;7.4GitLab&#xff1a;10.…

RHEL5下DNS配置详解3

view 是bind中的另外的一个技巧他在有防火墙的环境中非常有用。View允许你呈现出不同的配置文件给不同的客户&#xff0c;当你的服务器既要给内网的用户又要给外网的用户提供查询服务时使用view将是非常方便的。下其实访问控制列表就是一个有名字的地址匹配列表。它的语法格式为…

百叶窗效果显示图片源码(c#)

2019独角兽企业重金招聘Python工程师标准>>> 显示图片&#xff1a; this.pictureBox.Image Image.FromFile("image.jpg", false); 百叶窗有两种显示效果&#xff0c;一种是垂直百叶窗&#xff0c;另一种是水平百叶窗。 实现百叶窗显示图像有两种方式&…

16个顶级思维模型

思维模型会给你提供一种视角或思维框架&#xff0c;从而决定你观察事物和看待世界的视角。顶级的思维模型能提高你成功的可能性&#xff0c;并帮你避免失败。打造多元思维模型想法来自查理芒格&#xff0c;而查理芒格是沃伦巴菲特的得力助手。Farnam Street曾这样描述思维模型&…

使用BeetleX网关对Web应用进行灰度发布

灰度发布可以更有效地保障服务运作的可靠性&#xff0c;即能让服务得以更新的同时也不影响业务动作。BeetleX网关支持全动态化实时配置&#xff0c;对应用进行灰度发布可以说是非常便利。灰度发布在BeetleX网关中涉及到以下:添加新应用服务&#xff0c;测试路由配置&#xff0c…

17道因为太难而被禁用的Google面试题

即使是最成功的公司&#xff0c;它的招聘过程有时也会很不靠谱&#xff0c;经常会出一些奇怪的看似没有答案的面试问题&#xff0c;但标准答案却让应聘者还没来得及接近「起跑线」就被「退赛」了。Google 曾经就是这样的公司&#xff0c;招聘人员会出一些难为应聘者的高质量问题…

在 .NET Core 中构建 REST API

翻译自 Camilo Reyes 2020年8月26日的文章 《Build a REST API in .NET Core》 [1]REST API 可以使用简单的动词&#xff08;如 POST、PUT、PATCH 等&#xff09;将大型解决方案背后的复杂性隐藏起来。在本文中&#xff0c;Camilo Reyes 解释了如何在 .NET Core 中创建 REST AP…

一个检查SPN的小工具

如果大家配过kerberos的话会发现&#xff0c;AD本身并没有一个可以检查SPN的工具&#xff0c;而SPN一旦配重复的话会出现奇怪的错误&#xff0c;所以我就写了这么一个简单的工具。 截图 使用时候&#xff0c;输入你要查询的AD的名称或者IP&#xff0c;然后输入一个该域的用户信…

如果把整个因特网都印出来 你认为会怎么样

2019独角兽企业重金招聘Python工程师标准>>> 如果把整个因特网都印出来的话... 将会用掉 4500 万个墨盒&#xff0c;总计五十万公升的墨水。如果把这些墨水换成燃油&#xff0c;足够让747连飞 18,000 英里&#xff08;28,800 公里&#xff09;&#xff0c;从纽约不降…

ASP.NET Core中间件初始化探究

前言在日常使用ASP.NET Core开发的过程中我们多多少少会设计到使用中间件的场景&#xff0c;ASP.NET Core默认也为我们内置了许多的中间件&#xff0c;甚至有时候我们需要自定义中间件来帮我们处理一些请求管道过程中的处理。接下来&#xff0c;我们将围绕着以下几个问题来简单…

基于Python实现的微信好友数据分析

最近微信迎来了一次重要的更新&#xff0c;允许用户对”发现”页面进行定制。不知道从什么时候开始&#xff0c;微信朋友圈变得越来越复杂&#xff0c;当越来越多的人选择”仅展示最近三天的朋友圈”&#xff0c;大概连微信官方都是一脸的无可奈何。逐步泛化的好友关系&#xf…