我在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 });
这有一个简单的解决方法吗?
答案 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