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

Loz*_*yho 5 .net c# wcf file-upload

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

我有一个MessageContract类定义如下:

/// <summary>
/// Message contract for uploading document data together with a file stream
/// </summary>
[MessageContract]
public class DocumentDataFileUploadInfo : IDisposable
{
    /// some fields omitted for brevity

    /// <summary>
    /// The stream containing the file
    /// </summary>
    [MessageBodyMember(Order = 1)]
    public Stream FileByteStream;


    /// <summary>
    /// Dispose of the stream if necessary
    /// </summary>
    public void Dispose()        
    {
        try
        {
            if (FileByteStream != null)
            {
                FileByteStream.Close();
                FileByteStream.Dispose();
                FileByteStream = null;
            }
        }
        catch { }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

/// <summary>
/// Upload the given file into the database, as a stream
/// </summary>
/// <param name="fileInfoWithStream">The message containing all the information required for upload</param>
/// <returns></returns>             
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;
}
Run Code Online (Sandbox Code Playgroud)

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

<netTcpBinding>
  <binding name="netTcpStreamBinding"
           transferMode="Streamed"
           maxReceivedMessageSize="1099511627776" />
</netTcpBinding>
Run Code Online (Sandbox Code Playgroud)

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

if (!fileType.UploadPermitted)
{
    response.MetaData = InsertDocumentDataResult.FileTypeProhibited;
    return response;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

任何帮助非常感谢!