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<>- 这仍然导致流完成上传System.ServiceModel.OperationContext.Current.RequestContext.Abort();- 这会导致将CommunicationException抛出到客户端,并中止流上传但不会让我返回任何类型的失败原因我唯一的另一个选择(我可以看到)是如上所述中止请求,导致CommunicationException抛出,但为客户端添加新的服务方法以获取失败代码.我真的不想这样做,因为这应该是尽可能无状态的,我确信必须有一种简单的方法来取消服务器端的流上传.
任何帮助非常感谢!