Intro
我们有个接口需要给非研发人员使用,这个 API 大概功能是业务人员用来做简繁转换,原来有一个接口但是需要把要翻译的内容转成 json,返回的 response 也是 json,对于业务人员来说,用起来属实有些麻烦,所以我们要新加一个 API 用户可以直接输入要转换的文本,并将转换后的文本直接输出,用户输入的内容是纯文本
InputFormatter.
在 asp.net core mvc 中我们可以只用 input formatter 来进行扩展尚未支持的 media-type,之前我们有分享过一个自定义 content-type base-64 json 感兴趣的小伙伴也可以看一下
这次我们需要支持 text/plain
,默认的 input formatter 只有 json,并且框架里没有类似的东西,我们只能自己实现一个 formatter 了,在 GitHub 上找到一个类似的实现,没有在框架里,在测试代码里,可以参考:https://github.com/dotnet/aspnetcore/blob/2d3a0783fee9fc0b3a02a0813b363eb321fe8be2/src/Mvc/test/WebSites/FormatterWebSite/StringInputFormatter.cs#L10
读取 request body 的地方我们优化一下,就得到了下面的版本:
public sealed class PlainTextInputFormatter : TextInputFormatter
{
public PlainTextInputFormatter()
{
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/plain"));
SupportedEncodings.Add(Encoding.UTF8);
SupportedEncodings.Add(Encoding.Unicode);
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{
using var reader = context.ReaderFactory(context.HttpContext.Request.Body, encoding);
var rawContent = await reader.ReadToEndAsync();
return await InputFormatterResult.SuccessAsync(rawContent);
}
}
Sample
我们注册了这个 PlainTextInputFormatter
之后就可以支持 plain text 的输入了,参考下面的示例
在 Program 或者 Startup 中注册我们的 PlainTextInputFormatter
builder.Services.AddControllers(options =>
{
options.InputFormatters.Add(new PlainTextInputFormatter());
});
这样我们的应用就支持了 plain text 的 request body 了,再来看下我们的 API 示例:
[HttpPost("RawTextFormatterTest")]
[Consumes("text/plain")]
public Result RawTextFormatterTest([FromBody] string input)
{
return Result.Success<string>(input);
}
通过指定 [Consumes("text/plain")]
来指定 API 支持的 media type 为 text/plain
我们来看下 swagger 会是什么样子:
可以看到我们的 input 被正确的返回回来了,我们的 plain text 支持就可以了
More
Github 上提了 issue,希望框架能够默认支持 plain text,这样我们就不需要自己扩展了 https://github.com/dotnet/aspnetcore/issues/49168
如果大家也有这样的需求,也请大家帮忙支持一下这个 Github issue 哈,目前官方觉得用的场景较少,暂时不太考虑,如果大家需求多的话可能就会考虑加在框架里。