首页 > 解决方案 > Postman 发送到 ASP.net 的媒体类型不受支持

问题描述

我设置了一个简单的 Web Api 项目,我想向发布请求发送一个字符串,但无论我做什么,我都会得到“不支持的媒体类型”。我正在发送带有标题“Content-Type”的“值”:“text/plain”。

这是我的代码:

[HttpPost]
public ActionResult<string> Post([FromBody] string val) 
{
    return val + " success!";

}

有什么我做错了吗?

标签: asp.netasp.net-coreasp.net-web-api

解决方案


对于 ASP.NET Core 2.1 或更高版本, [ApiController]属性应用于控制器类。它可以自动推断[FromBody]您复杂操作方法参数的绑定源。但[FromBody]不会为简单类型(如字符串或 int)推断。因此,[FromBody]当需要该功能时,该属性应该用于简单类型。

Conten-Type:application/json所以你可以在邮递员中 发布一个简单的字符串,如下所示:在此处输入图像描述

不幸的是,ASP.NET Core 不允许您仅通过方法参数以任何有意义的方式捕获“原始”数据。有两种方法可以参考读取原始数据,如下所示:

1.最简单、侵入性最小但不那么明显的方法是使用一种方法来接受不带参数的 POST 或 PUT 数据,然后从以下位置读取原始数据Request.Body

[HttpPost]
public ActionResult<string> Post() 
{
    using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
    {
            var val = await reader.ReadToEndAsync();
    }
    return val + " success!";
}

2. 使用InputFormatter.

public class RawRequestBodyFormatter : InputFormatter
{
    public RawRequestBodyFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
    }

    /// <summary>
    /// Allow text/plain, application/octet-stream and no content type to
    /// be processed
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public override Boolean CanRead(InputFormatterContext context)
    {
        if (context == null) throw new ArgumentNullException(nameof(context));

        var contentType = context.HttpContext.Request.ContentType;
        if (string.IsNullOrEmpty(contentType) || contentType == "text/plain" ||
            contentType == "application/octet-stream")
            return true;

        return false;
    }

    /// <summary>
    /// Handle text/plain or no content type for string results
    /// Handle application/octet-stream for byte[] results
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
    {
        var request = context.HttpContext.Request;
        var contentType = context.HttpContext.Request.ContentType;

        if (string.IsNullOrEmpty(contentType) || contentType == "text/plain")
        {
            using (var reader = new StreamReader(request.Body))
            {
                var content = await reader.ReadToEndAsync();
                return await InputFormatterResult.SuccessAsync(content);
            }
        }
        return await InputFormatterResult.FailureAsync();
    }
}

InputFormatter 必须在 ConfigureServices() 启动代码中向 MVC 注册:

services.AddMvc(opts =>opts.InputFormatters.Insert(0, new RawRequestBodyFormatter()));

您可以参考此博客了解更多详细信息。


推荐阅读