让ASP.NET Web API支持POST纯文本格式(text/plain)的数据
今天在web api中遇到了这样一个问题,虽然api的参数类型是string,但只能接收post body中json格式的string,不能接收原始string。
web api是这样定义的:
public async Task<HttpResponseMessage> Post(string blogApp, int postId, [FromBody] string body)
{
}
以json格式向web api进行post能成功:
var response = await _httpClient.PostAsJsonAsync(
$"api/blogs/{blogApp}/posts/{postId}/comments",
body);
但以纯文本格式(content-type为text/plain)post,body的值却为空。
var response = await _httpClient.PostAsync(
$"api/blogs/{blogApp}/posts/{postId}/comments",
new StringContent(body)
);
研究后发现,这是由于对于content-type为text/plain的post请求,asp.net web api没有提供对应的MediaTypeFormatter,asp.net web api默认只提供了JsonMediaTypeFormatter与XmlMediaTypeFormatter。
所以要解决这个问题,需要自己实现一个PlainTextTypeFormatter,实现代码如下:
public class PlainTextTypeFormatter : MediaTypeFormatter
{
public PlainTextTypeFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
}
public override bool CanReadType(Type type)
{
return type == typeof(string);
}
public override bool CanWriteType(Type type)
{
return type == typeof(string);
}
public override async Task WriteToStreamAsync(Type type, object value,
Stream writeStream, HttpContent content, TransportContext transportContext)
{
using (var sw = new StreamWriter(writeStream))
{
await sw.WriteAsync(value.ToString());
}
}
public override async Task<object> ReadFromStreamAsync(Type type, Stream readStream,
HttpContent content, IFormatterLogger formatterLogger)
{
using (var sr = new StreamReader(readStream))
{
return await sr.ReadToEndAsync();
}
}
}
在上面的实现代码中,解决本文中的问题只需实现CanReadType()与ReadFromStreamAsync()。CanWriteType()与ReadFromStreamAsync()的实现是为了解决另外一个问题,详见:让ASP.NET Web API支持text/plain内容协商 。