流式 webHttpBinding 不是流式传输
我需要创建 WCF REST 服务来上传大文件。我将端点设置为流式 webHttpBinding,但它尚未成为流式。
服务示例:
[ServiceContract]
public interface IFiles
{
[OperationContract]
void UploadFile(Stream stream);
}
public class Files : IFiles
{
public void UploadFile(Stream stream)
{
const int BUFFER_SIZE = 64 * 1024;
byte[] buffer = new byte[BUFFER_SIZE];
using (TextWriter logWriter = new StreamWriter("d:\\UploadedFile.log"))
using (Stream fileStream = new FileStream("d:\\UploadedFile", System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
int readBytes = 0;
while (0 < (readBytes = stream.Read(buffer, 0, BUFFER_SIZE)))
{
fileStream.Write(buffer, 0, readBytes);
logWriter.WriteLine("{0}: {1} bytes saved", DateTime.Now, readBytes);
}
}
}
}
Web.config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="WebHttpBinding" maxBufferSize="65536" maxBufferPoolSize="524288"
maxReceivedMessageSize="1073741824" transferMode="Streamed" />
</webHttpBinding>
</bindings>
<services>
<service name="WcfService2.Files">
<endpoint behaviorConfiguration="WebHttpBehavior" binding="webHttpBinding"
bindingConfiguration="WebHttpBinding" name="Files" contract="WcfService2.IFiles" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="WebHttpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata />
<serviceDebug />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<httpRuntime maxRequestLength="500000" />
</system.web>
</configuration>
客户端代码:
using (Stream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlString);
request.Method = "POST";
request.ContentType = "application/octet-stream";
//request.ContentLength = fileStream.Length;
//request.AllowWriteStreamBuffering = false;
request.SendChunked = true;
Stream requestStream = request.GetRequestStream();
const int BUFFER_SIZE = 32 * 1024;
byte[] buffer = new byte[BUFFER_SIZE];
int readBytes = 0;
while (0 < (readBytes = fileStream.Read(buffer, 0, BUFFER_SIZE)))
{
requestStream.Write(buffer, 0, readBytes);
Console.WriteLine("{0}: {1} bytes sent", DateTime.Now, readBytes);
System.Threading.Thread.Sleep(200);
}
requestStream.Close();
WebResponse response = request.GetResponse();
}
只有在调用 requestStream.Close() 后才会调用方法 UploadFile 的代码。为什么?
I need create WCF REST service for uploading large files. I made endpoint as streamed webHttpBinding, but it have not became streamed.
Service example:
[ServiceContract]
public interface IFiles
{
[OperationContract]
void UploadFile(Stream stream);
}
public class Files : IFiles
{
public void UploadFile(Stream stream)
{
const int BUFFER_SIZE = 64 * 1024;
byte[] buffer = new byte[BUFFER_SIZE];
using (TextWriter logWriter = new StreamWriter("d:\\UploadedFile.log"))
using (Stream fileStream = new FileStream("d:\\UploadedFile", System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
int readBytes = 0;
while (0 < (readBytes = stream.Read(buffer, 0, BUFFER_SIZE)))
{
fileStream.Write(buffer, 0, readBytes);
logWriter.WriteLine("{0}: {1} bytes saved", DateTime.Now, readBytes);
}
}
}
}
Web.config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="WebHttpBinding" maxBufferSize="65536" maxBufferPoolSize="524288"
maxReceivedMessageSize="1073741824" transferMode="Streamed" />
</webHttpBinding>
</bindings>
<services>
<service name="WcfService2.Files">
<endpoint behaviorConfiguration="WebHttpBehavior" binding="webHttpBinding"
bindingConfiguration="WebHttpBinding" name="Files" contract="WcfService2.IFiles" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="WebHttpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata />
<serviceDebug />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<httpRuntime maxRequestLength="500000" />
</system.web>
</configuration>
Client code:
using (Stream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlString);
request.Method = "POST";
request.ContentType = "application/octet-stream";
//request.ContentLength = fileStream.Length;
//request.AllowWriteStreamBuffering = false;
request.SendChunked = true;
Stream requestStream = request.GetRequestStream();
const int BUFFER_SIZE = 32 * 1024;
byte[] buffer = new byte[BUFFER_SIZE];
int readBytes = 0;
while (0 < (readBytes = fileStream.Read(buffer, 0, BUFFER_SIZE)))
{
requestStream.Write(buffer, 0, readBytes);
Console.WriteLine("{0}: {1} bytes sent", DateTime.Now, readBytes);
System.Threading.Thread.Sleep(200);
}
requestStream.Close();
WebResponse response = request.GetResponse();
}
Code of method UploadFile is invoked only after requestStream.Close() is invoked. Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您想分部分发送它,您应该在 requestStream.Write() 之后的 while 循环中添加刷新,
因为流可能会缓存输出,直到需要发送它为止。请参阅 http://msdn.microsoft.com/en-我们/library/system.io.stream.flush.aspx
If you want to send it in parts you should add a flush in the while loop after the requestStream.Write()
This because streams may cache the output till it's nessecary to send it. See http://msdn.microsoft.com/en-us/library/system.io.stream.flush.aspx