我有一个WCF服务,返回一个类似于以下内容:
public Stream StreamFile(string filepath)
{
try
{
// Grab the file from wherever it is
// Throw an exception if it doesn't exist
return fileStream;
}
catch (Exception ex)
{
// Log the exception nicely in a place of my user's choosing
}
return Stream.Null;
}
Run Code Online (Sandbox Code Playgroud)
我曾经尝试返回null,但是如果找不到该文件,我就开始遇到这个问题:WCF - MessageBodyMember - Stream - "Value不能为null"
通过返回Stream.Null,我已经摆脱了这个错误,但现在我有另一个问题 - 我的客户如何知道我是否发回了Stream.Null?我不能/不应该检查长度,因为这些文件可能非常大,但即使它们不是,我也会遇到这个问题:在WCF客户端中查找Stream对象的长度?
这是我的(非常简化的)客户端代码,仅供后人使用,但仅仅下载Stream.Null的问题是我最终得到一个空文件,没有人喜欢它.
public FileInfo RetrieveFile(string fileToStream, string directory)
{
Stream reportStream;
string filePath = Path.Combine(directory, "file.txt");
using (Stream incomingStream = server.StreamFile(fileToStream))
{
if (incomingStream == null) throw new FileExistsException(); // Which totally doesn't work
using (FileStream outgoingStream = File.Open(filePath, FileMode.Create, FileAccess.Write))
{
incomingStream.CopyTo(outgoingStream);
}
}
return new FileInfo(filePath);
}
Run Code Online (Sandbox Code Playgroud)
看起来我只是在某种程度上错误地设计了这个方法,但我想不出一个更好的方法来做这个不涉及抛出未捕获的异常.有什么建议?
当 WCF 服务(或任何精心设计的服务)中发生意外情况时,客户端不能/不应该知道细节或关心。它只需要知道出了什么问题。
您应该允许异常出现而不捕获它,并且客户端会知道发生了故障并且操作失败,无论文件丢失、没有读取它的权限或者文件在磁盘上可能已损坏。这些对客户来说都不重要,因为除了与服务过于耦合之外,我无论如何都无法对这些信息做任何事情。
当然,在这种情况下,返回值毫无意义,实际上代理(通常)会处于故障状态并且不再可用。(这取决于您的会话模式和实例生活方式)。
请注意,如果您想让客户端了解错误并做出反应,您应该将这些错误设计为契约的一部分,并抛出一个FaultException<>
包装您在契约中显式声明的契约异常。这将使代理继续可用。你可以在这里阅读更多