日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

asp.net core 自定义 Content-Type

發布時間:2023/12/4 asp.net 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 分為 InputFormatter 和 OutputFormatter

  • 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.Json 和 Newtonsoft.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

總結

以上是生活随笔為你收集整理的asp.net core 自定义 Content-Type的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。