文章出處

今天在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內容協商


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()