我有一个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);
}
似乎我只是在某种程度上设计这个方法是错误的,但是我想不出一个更好的方法,不涉及抛出未捕获的异常。有什么建议吗?
答案 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