我如何检查Stream.Null?

我有一个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; } 

我曾经尝试返回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); } 

看起来我只是在某种程度上错误地设计了这个方法,但是我想不出更好的方法来做这个不涉及抛出未捕获的exception。 有什么建议?

当WCF服务(或任何设计良好的服务)发生意外情况时,客户端不能/不应该知道细节或关心。 所有它需要知道出了什么问题。

您应该允许exception上升而不捕获它,并且客户端会知道发生了故障并且操作失败,无论文件是否丢失,没有读取它的权限或者文件在磁盘上是否已损坏。 这些对客户来说都不重要,因为我无论如何都不能对信息做任何事情,除非与服务太耦合。

当然,在这种情况下,返回值是没有意义的,事实上代理将(通常)处于故障状态并且不再可用。 (这取决于您的会话模式和实例生活方式)。

请注意,如果您想让客户知道故障并做出反应,您应该将这些故障设计为合同的一部分,并抛出FaultException<>包装您在合同中明确声明的合同FaultException<>exception。 这将允许代理继续可用。 你可以在这里阅读更多