我如何检查Stream.Null?

时间:2015-07-28 05:07:14

标签: c# wcf stream

我有一个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 cannot be null"

通过返回Stream.Null,我已经摆脱了这个错误,但现在我还有另外一个问题 - 如果我发回Stream.Null,我的客户怎么知道?我不能/不应该检查长度,因为这些文件可能很大,但即使它们不是,我也会遇到这个问题:Find Length of Stream object in WCF Client?

这是我的(非常简化的)客户端代码,仅供后人使用,但仅仅下载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);
}

似乎我只是在某种程度上设计这个方法是错误的,但是我想不出一个更好的方法,不涉及抛出未捕获的异常。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

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

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

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

请注意,如果您想让客户了解故障并做出反应,您应该将这些故障设计为合同的一部分,并抛出final java.lang.String _jspx_method = request.getMethod(); if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD"); return; } 包装您在合同中明确声明的合同规定的异常。这将允许代理继续可用。您可以阅读更多here