Question

I have been trying to design a WCF file upload service and am getting the following error in my web application:

Type 'System.Web.HttpInputStream' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.

Based on this error, I have tried re-marking my FileTransfer class with DataContractAttribute and DataMemberAttribute but that didn't do anything:

[DataContractAttribute(Namespace = "FileTransfer")]
public class FileTransfer
{
    [DataMemberAttribute]
    public string GetUploadStatus;
    [DataMemberAttribute]
    public Tuple<string, int> DoUpload;
    [DataMemberAttribute]
    public int UploadFile;
    [DataMemberAttribute]
    public FileTransferInfo FileInfo;
    [DataMemberAttribute]
    public Stream FileByteStream;
}

I have tried accessing my Service Trace Log with Service Trace Viewer to see if I could get some more detail on this error. I found a number of errors with the following message:

The message with To 'http://localhost:1242/WebProj/filetransfer.svc/mex/mex' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.

Which would have been useful to me but I also found the same error for:

'http://localhost:1242/WebProj/auth.svc/mex/mex'

in the same trace and I was able to authenticate just fine without any errors which made me wonder if this error is something that I should be worrying about (if any body has a suggestion as to why there is a mex/mex at my endpoint, that would be great).

So, why can't 'System.Web.HttpInputStream' be serialized? I have provided the other important aspects of my code below. Maybe somebody out there can see something that I have missed?

[DataContract(Namespace = "FileTransfer")]
public class FileTransferInfo
{
    private string _guid;
    private int _flag;
    private long _fileSize;
    private string _fileName;
    private DateTime _lastUpdate;
    private FileTypeEnum _fileType;

    //REMOVED GETTERS AND SETTERS FOR SPACE 

 }

[ServiceContract(Namespace = "FileTransfer")]
public interface IFileTransferService
{
    [OperationContract(Name = "DoUpload")]
    Tuple<string, int> DoUpload(List<FileTransferInfo> request);

    [OperationContract(Action="UploadFile", Name="UploadFile")]
    int UploadFile(FileTransfer request);

}

Here is my UploadFile method that is returning the error.

int IFileTransferService.UploadFile(FileTransfer request)
{

    string uploadFolder = @"C:\TempMultiFileUploads\";
    int errCode = default(int);
    // parameters validation omitted for clarity
   try 
   {
        string filename = request.FileInfo.FileName;
        string filePath = Path.Combine(uploadFolder, filename);

        using (FileStream outfile = new FileStream(filePath, FileMode.Create))
        {
            const int bufferSize = 65536; // 64K

            Byte[] buffer = new Byte[bufferSize];
            int bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize);

            while (bytesRead > 0)
            {
                outfile.Write(buffer, 0, bytesRead);
                bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize);
            }
        }
    }
    catch (IOException e)
    {
        //System.IOException
        errCode = 800;
    }

   return errCode;

} 
    And, below is the endpoint, binding, and bahavior of my FileTransferService:

<endpoint name="MyFileTransferEP"
          address=""
          binding="basicHttpBinding"
          behaviorConfiguration="BasicHttpEPBehavior"
          bindingConfiguration="httpLargeDataStream"
          contract="FileTransfer.IFileTransferService" />   

<binding name="httpLargeDataStream" 
               closeTimeout="00:01:00" 
               openTimeout="00:01:00"
               receiveTimeout="00:10:00" 
               sendTimeout="00:01:00" 
               maxBufferSize="65536"
               maxReceivedMessageSize="2147483647" 
               messageEncoding="Mtom"
               transferMode="StreamedRequest">        

<behavior name="BasicHttpEPBehavior">
    <dataContractSerializer maxItemsInObjectGraph="2147483646" />
</behavior>  

Here is the code in my web application that calls the upload method:

FileTransferServiceClient upload = new FileTransferServiceClient();
HttpPostedFile m_objFile = default(HttpPostedFile);
FileTransfer transmit = new FileTransfer();

transmit.FileByteStream = m_objFile.InputStream;
transmit.FileInfo = new FileTransferInfo();
transmit.FileInfo.Guid = Guid.NewGuid().ToString();
transmit.FileInfo.Flag = default(int);
transmit.FileInfo.FileSize = m_objFile.ContentLength;
transmit.FileInfo.FileName = m_objFile.FileName;
transmit.FileInfo.LastUpdate = DateTime.Now;

int retParam = upload.UploadFile(transmit); // THROWS ERROR HERE

Thanks for your help.

Was it helpful?

Solution

You cannot define a data contract with a Stream member. You can either take or return a Stream as single parameter or define a message contract which has a single MessageBodyMember of type Stream, but can have multiple MessageHeaders. For more on large data streaming in WCF, please refer to this section of MSDN.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top