WCF MessageContract Problem
I am using VS 2008. I created a simple WCF service that includes a file upload procedure as one of its functions. I am using streaming, and the file being uploaded is passed in as a stream. Because the stream can be the only thing in the body, I set up a message contract to store filename and access credentials as header members (according to documentation I've seen, this should be a plausible solution to this scenario). The problem I have is that those header members are not available on the client to set values for when I add the web service reference. My server service contract looks like this:
Code:
<ServiceContract()> _
Public Interface IFileStreamingService
<OperationContract()> _
Sub Authenticate(ByVal Credentials As WCCredentials)
<OperationContract()> _
Sub UploadFile(ByVal UploadFile As WCUploadFileMessage)
<OperationContract()> _
Function DownloadFile(ByVal FileName As String, ByVal FileLocation As String, ByVal Credentials As WCCredentials) As System.IO.Stream
<OperationContract()> _
Function GetUpdateFileList(ByVal Credentials As WCCredentials) As WCFileInfo()
<OperationContract()> _
Function GetDataFileList(ByVal Credentials As WCCredentials) As WCFileInfo()
End Interface
I then have data contracts for the WCCredentials and WCFileInfo. Those are fine. Then I have the following for the WCUploadFileMessage:
Code:
<MessageContract()> _
Public Class WCUploadFileMessage
Private mCreds As WCCredentials
Private mFileName As String
Private mData As System.IO.Stream
<MessageHeader(MustUnderstand:=True)> _
Public Property FileName() As String
Get
Return Me.mFileName
End Get
Set(ByVal value As String)
Me.mFileName = value
End Set
End Property
<MessageHeader(MustUnderstand:=True)> _
Public Property Credentials() As WCCredentials
Get
Return Me.mCreds
End Get
Set(ByVal value As WCCredentials)
Me.mCreds = value
End Set
End Property
<MessageBodyMember(Order:=1)> _
Public Property Data() As System.IO.Stream
Get
Return Me.mData
End Get
Set(ByVal value As System.IO.Stream)
Me.mData = value
End Set
End Property
End Class
I've tried this approach using public properties, I've tried using just public variables for those. Nothing seems to work. After updating the web reference in my client application, the auto generated code for this message looks like this:
Code:
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3082"), _
System.SerializableAttribute(), _
System.Diagnostics.DebuggerStepThroughAttribute(), _
System.ComponentModel.DesignerCategoryAttribute("code"), _
System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=true, [Namespace]:="http://tempuri.org/")> _
Partial Public Class WCFileMessage
Private dataField() As Byte
'''<remarks/>
<System.Xml.Serialization.XmlElementAttribute(DataType:="base64Binary")> _
Public Property Data() As Byte()
Get
Return Me.dataField
End Get
Set
Me.dataField = value
End Set
End Property
End Class
I'm not sure how to set this up so I can set those header field values on the client, but that is what I need to be able to do. Right now they aren't showing up at all in the class on the client. Help on this is GREATLY appreciated. I am fairly new to WCF and have wrestling this one for hours now. Thanks!
Re: WCF MessageContract Problem
When you do the Update Service Reference in your client side project, do you tick the box labelled "Always generate message contracts" ?
Re: WCF MessageContract Problem
I tried it both ways. That wasn't the problem. It turned out, the problem lies in the While loop I was using to write the stream to a filestream.
Using the following to read the stream returned by DownloadFile() DOES NOT WORK!
While ((BytesRead = fs.Read(Buffer, 0, BufferLength) > 0))
SaveStream.Write(Buffer, 0, BytesRead)
End While
Using this code DOES WORK!
BytesRead = fs.Read(Buffer, 0, BufferLength)
While BytesRead > 0
SaveStream.Write(Buffer, 0, BytesRead)
BytesRead = fs.Read(Buffer, 0, BufferLength)
End While