如何从服务器端方法中止WCF文件上载

我正在使用WCF(.Net 4)从.Net 4 WinForms客户端应用程序上传文件到IIS服务器,用于内部系统。

我有一个MessageContract类定义如下:

 ///  /// Message contract for uploading document data together with a file stream ///  [MessageContract] public class DocumentDataFileUploadInfo : IDisposable { /// some fields omitted for brevity ///  /// The stream containing the file ///  [MessageBodyMember(Order = 1)] public Stream FileByteStream; ///  /// Dispose of the stream if necessary ///  public void Dispose() { try { if (FileByteStream != null) { FileByteStream.Close(); FileByteStream.Dispose(); FileByteStream = null; } } catch { } } } 

我的服务器端 WCF上传方法的内容如下:

  ///  /// Upload the given file into the database, as a stream ///  /// The message containing all the information required for upload ///  public DocumentDataFileUploadResponse UploadDocument(DocumentDataFileUploadInfo fileInfoWithStream) { byte[] documentBytes = null; string fileName = fileInfoWithStream.FileName; // create the message response DocumentDataFileUploadResponse response = new DocumentDataFileUploadResponse(); // check the file type being uploaded (from the database) FileType fileType = GetFileType(fileName, context); if (!fileType.UploadPermitted) { // we don't allow this file type response.MetaData = InsertDocumentDataResult.FileTypeProhibited; return response; } // get the contents of the stream as a byte array (extension method) documentBytes = fileInfoWithStream.FileByteStream.GetStreamContents(fileInfoWithStream.TransmissionSize, _uploadBufferSize, null, out cancelled); // save the document to disk/database // code omitted for brevity response.MetaData = InsertDocumentDataResult.Success; return response; } 

如果它很重要,我正在使用NetTcpBinding:

     

一切都很好,我可以上传非常大的文件没问题,客户端也可以取消上传。 唯一的问题是这个块:

 if (!fileType.UploadPermitted) { response.MetaData = InsertDocumentDataResult.FileTypeProhibited; return response; } 

这应该(并且确实)返回失败代码,因为不允许使用文件类型。 但是,只要服务方法完成,就会调用MessageContract类上的Dispose方法, Dispose流,然后客户端在获取返回代码之前完成整个流上载 ,即使服务器没有命中读取流的行。 必须有一些底层WCF流管道认为流需要在处理之前完成。

基本上,我希望SERVER能够取消流上传并返回失败代码。 我尝试过以下方法:

  • 抛出FaultException – 这仍然导致流完成上传
  • 调用System.ServiceModel.OperationContext.Current.RequestContext.Abort(); – 这会导致将CommunicationException抛出到客户端,并中止流上传但不会让我返回任何类型的失败原因
  • 暂时删除’MessageContract’类中的’Dispose()’。 没有不同。
  • 寻求到流的末尾 – 不支持。
  • 关闭流 – 立即使客户端发送所有数据。

我唯一的另一个选择(我可以看到)是如上所述中止请求,导致抛出CommunicationException ,但为客户端添加一个新的服务方法以获取失败代码。 我真的不想这样做,因为这应该是尽可能无状态的,我确信必须有一种简单的方法来取消服务器端的流上传。

任何帮助非常感谢!