我想知道是否有人遇到过这个:
我有一个WCF服务,它返回一个Stream(自定义我已创建)。
在下载过程中,可能是发生错误,我希望客户端知道它。
问题是,在下载过程中发生错误时,客户端流从Stream.Read接收“0字节”,并完成(成功)而不是异常/任何其他错误。
有什么解决方案吗?似乎WCF忽略了任何读取错误,然后才关闭流。
代码:
服务器:
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "Data")]
Stream GetFileStream();
}
public class Service1 : IService1
{
public System.IO.Stream GetFileStream()
{
return new MyCustomStream();
}
}
实现:
public class MyCustomStream : Stream
{
FileStream _Stream;
private bool wasRead = false;
public MyCustomStream()
{
_Stream = new FileStream(@"someFileOnDisk", FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
}
~MyCustomStream()
{
if (_Stream != null)
{
_Stream.Dispose();
}
}
public override int Read(byte[] buffer, int offset, int count)
{
if (!wasRead)
{
wasRead = true;
return _Stream.Read(buffer, offset, count);
}
else
{
throw new Exception("ERROR!!!!");
}
}
public override void Close()
{
_Stream.Close();
}
客户端:
internal static HttpWebRequest InitializeRequest(Uri url, string i_RelativeURL, int i_Timeout, string i_MethodType, string i_ContentType)
{
System.Net.HttpWebRequest newRequest = (HttpWebRequest)WebRequest.Create(CombineURI(url.AbsoluteUri, i_RelativeURL));
newRequest.Proxy = null; // We are not using proxy
newRequest.Timeout = i_Timeout;
newRequest.Method = i_MethodType;
newRequest.ContentType = i_ContentType;
return newRequest;
}
static void Main(string[] args)
{
HttpWebRequest request = InitializeRequest(new Uri(@"http://localhost/WCFTest/Service1.svc"), "data", 999999, "GET", "application/json");
using (WebResponse response = request.GetResponse())
{
using (Stream curStream = response.GetResponseStream())
{
byte[] buffer = new byte[2000000]; // ~2MB
int read = curStream.Read(buffer, 0, buffer.Length);
int blockToWrite = read;
while (read > 0)
{
// If we reach to ~1MB of data - write it to the disk
if (blockToWrite >= 1000000)
{
blockToWrite = 0;
}
read = curStream.Read(buffer, blockToWrite, buffer.Length - blockToWrite); // Returns 0 if exception occurs on server side.
blockToWrite += read;
}
}
}
}