从Web API方法获取原始POST数据

时间:2012-11-05 06:09:52

标签: c# asp.net-web-api

我在ApiController类中有以下Web API方法:

public HttpResponseMessage Post([FromBody]byte[] incomingData)
{
  ...
}

我希望incomingData成为POST的原始内容。但似乎Web API堆栈尝试使用JSON格式化程序解析传入数据,这会导致客户端上的以下代码失败:

new WebClient().UploadData("http://localhost:15134/api/Foo", new byte[] { 1, 2, 3 });

这有一个简单的解决方法吗?

6 个答案:

答案 0 :(得分:50)

对于遇到此问题的其他人,解决方案是定义不带参数的POST方法,并通过Request.Content访问原始数据:

public HttpResponseMessage Post()
{
  Request.Content.ReadAsByteArrayAsync()...
  ...

答案 1 :(得分:25)

如果您需要除模型参数之外的原始输入以便于访问,您可以使用以下内容:

using (var contentStream = await this.Request.Content.ReadAsStreamAsync())
{
    contentStream.Seek(0, SeekOrigin.Begin);
    using (var sr = new StreamReader(contentStream))
    {
        string rawContent = sr.ReadToEnd();
        // use raw content here
    }
}

秘密是在尝试读取数据之前使用stream.Seek(0, SeekOrigin.Begin)重置流。

答案 2 :(得分:13)

其他答案建议删除输入参数,但这会破坏所有现有代码。要正确回答这个问题,更简单的解决方案是创建一个看起来像这样的函数(感谢Christoph下面的代码):

public HttpResponseMessage Post ([FromBody]byte[] incomingData)
{
    string rawData = getRawPostData().Result;

    // log it or whatever

    return Request.CreateResponse(HttpStatusCode.OK);
}

然后在您的网络API呼叫中获取原始发布数据,如下所示:

JavaRDD<String> people = sc.textFile("s3://path");

答案 3 :(得分:6)

我接受了LachlanB的答案,并将其放在一个实用程序类中,使用一个静态方法,我可以在所有控制器中使用。

public class RawContentReader
{
    public static async Task<string> Read(HttpRequestMessage req)
    {
        using (var contentStream = await req.Content.ReadAsStreamAsync())
        {
            contentStream.Seek(0, SeekOrigin.Begin);
            using (var sr = new StreamReader(contentStream))
            {
                return sr.ReadToEnd();
            }
        }
    }
}

然后我可以用我的任何ApiController方法调用它:

string raw = await RawContentReader.Read(this.Request);

答案 4 :(得分:4)

在MVC 6中,请求似乎没有&#39;内容&#39;属性。这就是我最终做的事情:

[HttpPost]
public async Task<string> Post()
{
    string content = await new StreamReader(Request.Body).ReadToEndAsync();
    return "SUCCESS";
}

答案 5 :(得分:0)

或者干脆

string rawContent = await Request.Content.ReadAsStringAsync();

确保在原始请求被处理之前在相同线程上运行上面的行

注意:这是针对 ASP.NET MVC 5