我有一个以流(无缓冲)模式运行的WCF REST服务,该模式在HTTP请求正文中接收文件上载为原始字节。在读取传入流(MessageBodyStream
)之前,我检查请求标头并确保Content-Length
适合该特定操作。
如果Content-Length
大于允许的大小,我想立即返回错误响应(通过抛出WebFaultException
)而不等待传输的其余请求。< / p>
但是,即使抛出异常,WCF似乎也会尝试将流读取到最后 - 如果客户端正在发送50 MB文件,则在发送响应之前将传输所有50 MB。
有没有办法避免这种情况,并中断接收HTTP请求?
相关问题:Why is WCF reading input stream to EOF on Close()?
编辑:添加了代码摘录
OperationContract
和上传帮助方法:
[OperationContract]
[WebInvoke(UriTemplate = /* ... */, Method = "POST",
ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
public void UploadMyFile(string guid, Stream fileStream)
{
string targetPath = /* targetPath */;
UploadFile(fileStream, targetPath, /* targetFileName */);
}
private bool UploadFile(Stream stream, string targetDirectory,
string targetFileName = null, int maximumSize = 1024 * 500,
Func<string, bool> tempFileValidator = null)
{
int size = 0;
int.TryParse(IncomingRequest.Headers[HttpRequestHeader.ContentLength], out size);
if (size == 0)
{
ThrowJsonException(HttpStatusCode.LengthRequired, "Valid Content-Length required");
}
else if (size > maximumSize)
{
ThrowJsonException(HttpStatusCode.RequestEntityTooLarge, "File is too big");
}
if (!FileSystem.SaveFileFromStream(stream, targetDirectory, targetFileName, tempFileValidator))
{
ThrowJsonException(HttpStatusCode.InternalServerError, "Saving file failed");
}
return true;
}
答案 0 :(得分:1)
您可以编写消息检查器组件,它可以拦截请求的正文和上下文。
然后,您可以在检查消息/上下文后抛出异常(如果您愿意)。
HTH
答案 1 :(得分:0)
HttpWebRequest
并且通常HTTP请求不支持下面的流式传输,这是由服务器端概念的分块编码实现的。
我刚才也回答了这个问题: IIS7 refuses chunked-encoded file upload
当您写入请求流时,它会在本地缓冲,直到发送为止,因为它必须伪造内容长度标题。您可以在 fiddler 中验证这一点。