无法从web api读取正文数据POST
我想从新的Asp.Net Web Api中的请求中提取一些数据。我有一个处理程序设置是这样的:无法从web api读取正文数据POST
public class MyTestHandler : DelegatingHandler
{
protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
if (request.Content.IsFormData())
{
request.Content.ReadAsStreamAsync().ContinueWith(x => {
var result = "";
using (var sr = new StreamReader(x.Result))
{
result = sr.ReadToEnd();
}
Console.Write(result);
});
}
return base.SendAsync(request, cancellationToken);
}
}
这是我的http请求:
POST http://127.0.0.1/test HTTP/1.1
Connection: Keep-Alive
Content-Length: 29
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue
Host: 127.0.0.1
my_property=my_value
的问题是,无论我如何努力从request.Content
读取信息,它总是空的。我试过
request.Content.ReadAsStreamAsync
request.Content.ReadAsFormDataAsync
request.Content.ReadAs<FormDataCollection>
以及
[HttpGet,HttpPost]
public string Index([FromBody]string my_property)
{
//my_property == null
return "Test";
}
无它是否工作。我无法从身体中获取数据。我在Windows 7的IIS内托管并使用Fiddler提交请求。我究竟做错了什么?
问题是,与Web Api身体只能被读取一次。我有一个运行的HTTP模块,它记录了请求的所有细节,并正在读取正文。
所以,做这样登录不可能,对吗? – kooldave98 2015-05-06 11:30:14
有可能,您需要首先使用LoadIntoBufferAsync()方法将其读入缓冲区。这使内容仍可用于基本方法。更多从这里https://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi – Tom 2016-10-14 12:46:41
我有同样的问题,最后选择不写入日志中的内容。 我与记录Content-Type和Content-Length一起生活。
但是,尽可能将所有内容写入日志总是一个好主意。
但是现在看起来和WebApi一样,我们无法做到这一点。
这是丑陋的,但是你把它从最初的修修补补,你可以,事实上,更换DelegatingHandler内容似乎...
protected override Task SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
Stream stream = new MemoryStream();
request.Content.ReadAsStreamAsync().Result.CopyTo(stream);
stream.Seek(0,SeekOrigin.Begin);
// copy off the content "for later"
string query = new StreamReader(stream).ReadToEnd();
stream.Seek(0,SeekOrigin.Begin);
// if further processing depends on content type
// go ahead and grab current value
var contentType = request.Content.Headers.ContentType;
request.Content = new StreamContent(stream);
request.Content.Headers.ContentType = contentType;
return base.SendAsync(request, cancellationToken);
}
我不知道这是否是好形式或坏的(坏疑),但是......它似乎能够工作,遵循我见过的模型,推荐给那些需要使用DelegatingHandler“在途中”修改请求标头和内容的人。
您的里程可能差别很大。
我根据我对brmore的代码的回答;
此功能可以在任何处理器
private string SafeReadContentFrom(HttpRequestMessage request)
{
var contentType = request.Content.Headers.ContentType;
var contentInString = request.Content.ReadAsStringAsync().Result;
request.Content = new StringContent(contentInString);
request.Content.Headers.ContentType = contentType;
return contentInString;
}
可以先创建一个提供安全的阅读内容。 MultipartMemoryStreamProvider()
然后Request.Content.ReadAsMultipartAsync(provider)
; 然后阅读内容
public async Task<IHttpActionResult> Post(int id, string type)
{
// Check if the request contains multipart/form-data.
if(!Request.Content.IsMimeMultipartContent("form-data"))
return BadRequest("Unsupported media type");
try
{
var azureManager = new AzureManager();
var imageManager = new ImageManager();
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var assets = new List<Asset>();
foreach (var file in provider.Contents)
{
var stream = await file.ReadAsStreamAsync();
var guid = Guid.NewGuid();
string blobName = guid.ToString();
await azureManager.UploadAsync(blobName, stream);
var asset = new Asset
{
PropertyId = id,
FileId = guid,
FileName = file.Headers.ContentDisposition.FileName.Trim('\"').ToLower(),
FileSize = file.Headers.ContentLength ?? 0,
MimeType = file.Headers.ContentType.MediaType.ToLower()
};
if (type == "photos")
{
asset.Type = AssetType.Photo;
// Resize and crop copies to 16:9
using (MemoryStream thumb = imageManager.ResizeImage(stream, 320, 180))
{
await azureManager.UploadAsync(blobName, thumb, BlobContainers.Thumbs);
}
using (MemoryStream photo = imageManager.ResizeImage(stream, 1024, 576))
{
await azureManager.UploadAsync(blobName, photo, BlobContainers.Photos);
}
}
else
asset.AssumeType();
assets.Add(asset);
}
db.Assets.AddRange(assets);
await db.SaveChangesAsync();
return Ok(new { Message = "Assets uploaded ok", Assets = assets });
}
catch (Exception ex)
{
return BadRequest(ex.GetBaseException().Message);
}
}
这适用于我。
[HttpPost]
public IHttpActionResult Index(HttpRequestMessage request)
{
var form = request.Content.ReadAsFormDataAsync().Result;
return Ok();
}
如果知道类似于wcftestclient.exe的独立客户端是否产生类似结果将会有所帮助。 – 2012-08-17 14:31:13
试图运行,但它不会,因为它说我的端点没有任何元数据。 – Micah 2012-08-17 14:43:29
这看起来很奇怪。您是否有理由选择通过提供的[HttpGet]和[HttpPost]方法进行数据传输的方法? – 2012-08-17 14:46:49