<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Comment Feed for Channel 9 - Silverlight 3 File Transfer Application</title>
	<atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application/RSS"></atom:link>
	<image>
		<url>http://ecn.channel9.msdn.com/o9/c4f/images/9876572_100.jpg</url>
		<title>Channel 9 - Silverlight 3 File Transfer Application</title>
		<link></link>
	</image>
	<description>Every once in a while I will run into a situation where I need to send a file to someone, but struggle to find an easy way of doing it.&amp;nbsp; Instant messenger programs usually work until you run into a situation where someone just cannot send or receive a file
 from chat client whether it&#39;s due to firewalls, differing client versions, or multi-IM incompatibilities.&amp;nbsp; Other times, I will try to send the file via email just to find out that the person&#39;s email server blocks specific extensions.&amp;nbsp; This quick application
 will allow two users to quickly and easily connect to a Silverlight 3 client and send each other files.&amp;nbsp;
 
Overview
In this application, a user will connect to the Silverlight application and choose to either host or join a session.&amp;nbsp; If a user decides to host a session, he or she will be given a random eight character session key, and he or she will be in a waiting status
 until another user connects.&amp;nbsp; When a user wishes to connect to the host, he or she can supply the host&#39;s session key which will establish a connection between the two users.&amp;nbsp; Once connected, the users will be able to send files to one another, and will also
 be able to chat with each other via simple text messages. 

 
Polling Duplex
Sending a file from one client application to another requires a common central point in order to properly route the message from one user to another.&amp;nbsp; Since it is easy to host a Silverlight application in an ASP.NET page, we will use an ASP.NET back end
 to manage all communications between all connected users.&amp;nbsp; In order to do this, we must be able to host a service that is able to accept incoming messages from the Silverlight client, and perform a push back out to the intended recipient.&amp;nbsp; This is accomplished
 by using the WCF Polling Duplex (System.ServiceModel.PollingDuplex.dll) channel.&amp;nbsp; Silverlight 3 allows us to directly add a service reference to a service of this type, and handles all of the complexities for us.&amp;nbsp; I began by using the
 DuplexService.cs file from a sample application from MIX09 when Silverlight 3 beta was released.&amp;nbsp; The code starts us out with a couple of base abstract classes, and interfaces that we must inherit from in order to create our own service.&amp;nbsp;
 
FileSendService
The two main things we need to do in order to create our own service is to define custom message types that will be used for communication, and override the base
DuplexService class to properly handle these messages.&amp;nbsp; We will create our custom message types by using
DuplexMessage (defined in DuplexService.cs) as our base class.&amp;nbsp; Our message classes must be defined with the
[DataContract] attribute, and the the member variables must be public and contain the
[DataMember] attribute.&amp;nbsp; This will allow our Silverlight client project to share these definitions using a service reference.&amp;nbsp; Additionally, the Duplex message class must have the
[KnownType] attribute for each descendant message created. 
&amp;nbsp;C# 

[KnownType(typeof(HostSessionMessage))][KnownType(typeof(JoinSessionMessage))][KnownType(typeof(FileBeginUploadMessage))][KnownType(typeof(FileTransferBytesMessage))]public class DuplexMessage { } 


[DataContract]public class HostSessionMessage : DuplexMessage{    [DataMember]    public string Username;}[DataContract]public class JoinSessionMessage : DuplexMessage{    [DataMember]    public string Username;    [DataMember]    public string SessionKey;}[DataContract]public class FileBeginUploadMessage : DuplexMessage{    [DataMember]    public string FileName;    [DataMember]    public long TotalBytes;}[DataContract]public class FileTransferBytesMessage : DuplexMessage{    [DataMember]    public long StartByte;    [DataMember]    public long PacketSize;    [DataMember]    public byte[] Bytes;    [DataMember]    public bool EndFile;}


VB 

&amp;lt;DataContract(Namespace := &amp;quot;http://samples.microsoft.com/silverlight2/duplex&amp;quot;), KnownType(GetType(HostSessionMessage)), KnownType(GetType(JoinSessionMessage)), KnownType(GetType(FileBeginUploadMessage)), KnownType(GetType(FileTransferBytesMessage))&amp;gt; _Public Class DuplexMessageEnd Class



&amp;lt;DataContract()&amp;gt; _Public Class HostSessionMessage    Inherits DuplexMessage    &amp;lt;DataMember()&amp;gt; Public Username As StringEnd Class&amp;lt;DataContract()&amp;gt; _Public Class JoinSessionMessage    Inherits DuplexMessage    &amp;lt;DataMember()&amp;gt; Public Username As String    &amp;lt;DataMember()&amp;gt; Public SessionKey As StringEnd Class&amp;lt;DataContract()&amp;gt; _Public Class FileTransferBytesMessage    Inherits DuplexMessage    &amp;lt;DataMember()&amp;gt; Public StartByte As Long    &amp;lt;DataMember()&amp;gt; Public PacketSize As Long    &amp;lt;DataMember()&amp;gt; Public Bytes() As Byte    &amp;lt;DataMember()&amp;gt; Public EndFile As BooleanEnd Class&amp;lt;DataContract()&amp;gt; _Public Class FileBeginUploadMessage    Inherits DuplexMessage    &amp;lt;DataMember()&amp;gt; Public FileName As String    &amp;lt;DataMember()&amp;gt; Public TotalBytes As LongEnd Class


The next step is to create our FileSendService class which descends from the
DuplexService class as described above.&amp;nbsp; We override the 
OnMessage method so that we can do custom processing based on the type of message sent as shown below.&amp;nbsp;
 
C# 

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]public class FileSendService : DuplexService{    private List&amp;lt;SessionConnectionInfo&amp;gt; sessionConnections = new List&amp;lt;SessionConnectionInfo&amp;gt;();    {...}    protected override void OnMessage(string sessionId, DuplexMessage data)    {        if (data is HostSessionMessage)            CreateHostSession(data as HostSessionMessage);        else if (data is JoinSessionMessage)            JoinSession(data as JoinSessionMessage);        else if (data is FileBeginUploadMessage)            StartSendFile(data as FileBeginUploadMessage);        else            SendMessage(data);    }    }
        else if (data is JoinSessionMessage)            JoinSession(data as JoinSessionMessage);        else if (data is FileBeginUploadMessage)            StartSendFile(data as FileBeginUploadMessage);        else            SendMessage(data);    }    }
    }    }


&amp;nbsp;VB 

Public Class FileSenderServiceFactory    Inherits DuplexServiceFactory(Of FileSendService)End Class&amp;lt;AspNetCompatibilityRequirements(RequirementsMode := AspNetCompatibilityRequirementsMode.Allowed)&amp;gt; _Public Class FileSendService    Inherits DuplexService    Private sessionConnections As New List(Of SessionConnectionInfo)()    ...    Protected Overrides Sub OnMessage(ByVal sessionId As String, ByVal data As DuplexMessage)        If TypeOf data Is HostSessionMessage Then            CreateHostSession(TryCast(data, HostSessionMessage))        ElseIf TypeOf data Is JoinSessionMessage Then            JoinSession(TryCast(data, JoinSessionMessage))        ElseIf TypeOf data Is FileBeginUploadMessage Then            StartSendFile(TryCast(data, FileBeginUploadMessage))        Else            SendMessage(data)        End If    End SubEnd Class


Since we are going to have to keep track of each host and user connected to that host, we will create a class,&amp;nbsp;
SessionConnectionInfo, to manage the relevant data.&amp;nbsp; When a user decides to host a session, our
OnMessage method will receive a HostSessionMessage which will scan our List&amp;lt;SessionConnectionInfo&amp;gt; to see if there is another host with the same username.&amp;nbsp; If not found, a new
SessionConnectionInfo object is created along with a randomly generated session key.&amp;nbsp; When a user attempts to join a session, the
OnMessage method will receive a JoinSessionMessage containing a session key and the name of the user joining the session.&amp;nbsp; The service will search for a
SessionConnectionInfo object containing that session key, and if found, establishes a connection between the two users.&amp;nbsp;
 
&amp;nbsp;C# 

public class SessionConnectionInfo{    public string HostUserName { get; set; }    public string ConnectedUsername { get; private set; }    public string SessionKey { get; set; }    public string ConnectedUserInternalSession { get; private set; }    public string HostInternalSession { get; set; }    public bool UserConnected    {        get { return ConnectedUserInternalSession != string.Empty; }    }    public SessionConnectionInfo()    {        ConnectedUserInternalSession = string.Empty;        ConnectedUsername = string.Empty;    }    ....}

VB&amp;nbsp; 

Public Class SessionConnectionInfo    Private privateHostUserName As String    Public Property HostUserName() As String        Get            Return privateHostUserName        End Get        Set(ByVal value As String)            privateHostUserName = value        End Set    End Property    Private privateConnectedUsername As String    Public Property ConnectedUsername() As String        Get            Return privateConnectedUsername        End Get        Private Set(ByVal value As String)            privateConnectedUsername = value        End Set    End Property    Private privateSessionKey As String    Public Property SessionKey() As String        Get            Return privateSessionKey        End Get        Set(ByVal value As String)            privateSessionKey = value        End Set    End Property    Private privateConnectedUserInternalSession As String    Public Property ConnectedUserInternalSession() As String        Get            Return privateConnectedUserInternalSession        End Get        Private Set(ByVal value As String)            privateConnectedUserInternalSession = value        End Set    End Property    Private privateHostInternalSession As String    Public Property HostInternalSession() As String        Get            Return privateHostInternalSession        End Get        Set(ByVal value As String)            privateHostInternalSession = value        End Set    End Property    Public ReadOnly Property UserConnected() As Boolean        Get            Return ConnectedUserInternalSession &amp;lt;&amp;gt; String.Empty        End Get    End Property    Public Sub New()        ConnectedUserInternalSession = String.Empty        ConnectedUsername = String.Empty    End SubEnd Class


Client Side
Now that we have the basic server side complete, we can add a service reference, and create the necessary service reference.&amp;nbsp; Our service is hosted within ASP.NET via a simple xml file (see
FileSendService.svc), which allows our Silverlight project to see it. 

 
Be sure to mark the checkbox “Always generate message contracts”.&amp;nbsp; Note that your web portion of the project must be compiled before you will be able to “Discover” the service. 
We will now have access to the DuplexServiceClient class which will allow us to send and receive messages to the server.&amp;nbsp; We instantiate the service as shown below.&amp;nbsp; In order to do this, you must manually add a reference to
System.ServiceModel.PollingDuplex assembly. 
C# 

private DuplexServiceClient fileDuplexService;private CustomBinding binding = new CustomBinding(    new PollingDuplexBindingElement(),    new BinaryMessageEncodingBindingElement(),    new HttpTransportBindingElement());public MainPage(){    InitializeComponent();    fileDuplexService = new DuplexServiceClient(binding, new EndpointAddress(&amp;quot;http://localhost:9797/FileSendService.svc&amp;quot;));    ...}


VB 

Private fileDuplexService As DuplexServiceClientPrivate binding As New CustomBinding(New PollingDuplexBindingElement(), New BinaryMessageEncodingBindingElement(), New HttpTransportBindingElement())     Public Sub New()&amp;nbsp;&amp;nbsp;&amp;nbsp; InitializeComponent()    fileDuplexService = New DuplexServiceClient(binding, New EndpointAddress(&amp;quot;http://localhost:9797/FileSendService.svc&amp;quot;))End Sub 


Note that at the time of this writing, adding the service reference does not properly create the
ServiceReferences.ClientConfig file.&amp;nbsp; This is the reason the above is done using code. 
Now that our service is setup, we need to set it up to handle sending and receiving of messages.&amp;nbsp;&amp;nbsp; In order to send a message, we must first create a
DupexMessage (or a descendant), and use the SendToServiceAsync method.&amp;nbsp; This requires a
SendToService object which will contain the message, and an optional
userState object which we can use to tag the request.&amp;nbsp; In this case, we will pass an enum value which represents the status of our upload.&amp;nbsp; In the example below, when the user clicks on the send file button, after choosing the file, we open
 our file, and send a FileBeginUpload message which contains the file name and its size.&amp;nbsp; Note that the server is set to deny any file that is greater than 20 million bytes. 
C# 

private void btnSendFile_Click(object sender, RoutedEventArgs e) {     OpenFileDialog openFileDialog = new OpenFileDialog();     openFileDialog.Multiselect = false;     openFileDialog.ShowDialog();     if (openFileDialog.File != null)     {         fileToSend = openFileDialog.File.OpenRead();         FileBeginUploadMessage fsm = new FileBeginUploadMessage();         fsm.FileName = openFileDialog.File.Name;         fsm.TotalBytes = openFileDialog.File.Length;         fileDuplexService.SendToServiceAsync(new SendToService(fsm), FileSendState.FileStart);         ....     } }


VB 

Private Sub btnSendFile_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)    Dim openFileDialog As New OpenFileDialog()    openFileDialog.Multiselect = False    openFileDialog.ShowDialog()    If openFileDialog.File IsNot Nothing Then        fileToSend = openFileDialog.File.OpenRead()        Dim fsm As New FileBeginUploadMessage()        fsm.FileName = openFileDialog.File.Name        fsm.TotalBytes = openFileDialog.File.Length        totalBytesSent = 0        fileDuplexService.SendToServiceAsync(New SendToService(fsm), FileSendState.FileStart)        ....    End IfEnd Sub


The service object fires two main events that need to be handled: SendToServiceCompleted and
SendToClientReceived. SendToServiceCompleted is the event which is fired after the server acknowledges that it has received and processed a message that the client has sent.&amp;nbsp; Once the server receives and processes the
FileBeginUploadMessage, the event handler below will receive the results.&amp;nbsp; In this case, if there isn&#39;t an error, and the value of
userState is FileSendState.FileStart,&amp;nbsp; the method will send a
FileTransferBytesMessage which will send the bytes from the file.&amp;nbsp;
 
C# 

private void FileDuplexServiceSendToServiceCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e){    if (e.Error == null)    {        {...}        if ((FileSendState)e.UserState == FileSendState.FileEnd)        {            fileToSend.Close();            fileProgress.Value = 100;            return;        }        if ((FileSendState)e.UserState == FileSendState.FileStart || (FileSendState)e.UserState == FileSendState.FileContinue)        { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...            FileTransferBytesMessage fileMessage = new FileTransferBytesMessage();            fileMessage.StartByte = totalBytesSent;            fileMessage.EndFile = false;            fileMessage.PacketSize = CHUNK;            ...            byte[] bytes = new byte[numBytesToRead];            fileToSend.Read(bytes, 0, numBytesToRead);            totalBytesSent &amp;#43;= numBytesToRead;            fileMessage.Bytes = bytes;            if (fileMessage.EndFile)                fileDuplexService.SendToServiceAsync(new SendToService(fileMessage), FileSendState.FileEnd);            else                fileDuplexService.SendToServiceAsync(new SendToService(fileMessage), FileSendState.FileContinue);        }    }} 

VB 

Private Sub FileDuplexServiceSendToServiceCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)    If e.Error Is Nothing Then        If e.UserState Is Nothing Then            Return        End If        If CType(e.UserState, FileSendState) = FileSendState.FileEnd Then            fileToSend.Close()            fileProgress.Value = 100            Return        End If        If CType(e.UserState, FileSendState) = FileSendState.FileStart OrElse CType(e.UserState, FileSendState) = FileSendState.FileContinue Then            ...            Dim fileMessage As New FileTransferBytesMessage()            fileMessage.StartByte = totalBytesSent            fileMessage.EndFile = False            fileMessage.PacketSize = CHUNK            ...            Dim bytes(numBytesToRead - 1) As Byte            fileToSend.Read(bytes, 0, numBytesToRead)            totalBytesSent &amp;#43;= numBytesToRead            fileMessage.Bytes = bytes            If fileMessage.EndFile Then                fileDuplexService.SendToServiceAsync(New SendToService(fileMessage), FileSendState.FileEnd)            Else                fileDuplexService.SendToServiceAsync(New SendToService(fileMessage), FileSendState.FileContinue)            End If        End If    End IfEnd Sub


The SendToClientReceived event is fired when a message has been sent from the service.&amp;nbsp; In this case, the client will check to see which message was received and process it accordingly.&amp;nbsp; The method below shows that when a
FileBeginUpload message is received, the user is prompted to accept or deny the file.&amp;nbsp; If the user does not accept the file, a
FileDenyMessage will be sent which will notify the sender to stop sending bytes.&amp;nbsp; If accepted, file bytes are added to a buffer.&amp;nbsp;
 
C# 

private void FileDuplexServiceSendToClientReceived(object sender, SendToClientReceivedEventArgs e){    if (e.Error == null)    {        if (e.request.msg is ClientConnectedMessage)        {            ClientConnectedMessage msg = (ClientConnectedMessage)e.request.msg;            AddMsgToListbox(msg.Username &amp;#43; &amp;quot; has just connected.&amp;quot;);            connectedTo = msg.Username;            UIState = UIState.Chat;        }        else if (e.request.msg is HostSessionServerMessage)        {            HostSessionServerMessage hssm = e.request.msg as HostSessionServerMessage;            if (hssm.Failed) {...}            SessionCreated(hssm);        }        else if (e.request.msg is JoinSessionServerMessage)        {            JoinSessionServerMessage jssm = e.request.msg as JoinSessionServerMessage;            if (jssm.Failed) {....}            SessionJoined(jssm);        }        else if (e.request.msg is FileBeginUploadMessage )        {            FileBeginUploadMessage fsm = (FileBeginUploadMessage)e.request.msg;            int sizeInKB = (int)fsm.TotalBytes / 1024;            totalRevd = 0;            if (MessageBox.Show(connectedTo &amp;#43; &amp;quot; would like to send you the file: &amp;quot; &amp;#43; fsm.FileName &amp;#43; &amp;quot;, Size: &amp;quot; &amp;#43; sizeInKB &amp;#43; &amp;quot;.  Would you like to receive this file?&amp;quot;, &amp;quot;File Upload&amp;quot;, MessageBoxButton.OKCancel) == MessageBoxResult.OK)            {                bytesReceived = new List&amp;lt;byte&amp;gt;((int)fsm.TotalBytes);                fileNameReceiving = fsm.FileName;                ....            }            else            {                fileDuplexService.SendToServiceAsync(new SendToService(new FileDenyMessage()));            }        }        else if (e.request.msg is FileTransferBytesMessage)        {            if (bytesReceived == null)                return;            FileTransferBytesMessage fm = (FileTransferBytesMessage)e.request.msg;            bytesReceived.AddRange(fm.Bytes);            ....        }        else {....}    }}


VB 

Private Sub FileDuplexServiceSendToClientReceived(ByVal sender As Object, ByVal e As SendToClientReceivedEventArgs)    If e.Error Is Nothing Then        If TypeOf e.request.msg Is ClientConnectedMessage Then            Dim msg As ClientConnectedMessage = CType(e.request.msg, ClientConnectedMessage)            AddMsgToListbox(msg.Username &amp;amp; &amp;quot; has just connected.&amp;quot;)            connectedTo = msg.Username            UIState = UIState.Chat        ElseIf TypeOf e.request.msg Is HostSessionServerMessage Then            Dim hssm As HostSessionServerMessage = TryCast(e.request.msg, HostSessionServerMessage)            If hssm.Failed Then ...            SessionCreated(hssm)        ElseIf TypeOf e.request.msg Is JoinSessionServerMessage Then            Dim jssm As JoinSessionServerMessage = TryCast(e.request.msg, JoinSessionServerMessage)            If jssm.Failed Then ...            SessionJoined(jssm)        ElseIf TypeOf e.request.msg Is FileBeginUploadMessage Then            Dim fsm As FileBeginUploadMessage = CType(e.request.msg, FileBeginUploadMessage)            Dim sizeInKB As Integer = CInt(Fix(fsm.TotalBytes)) / 1024            totalRevd = 0            If MessageBox.Show(connectedTo &amp;amp; &amp;quot; would like to send you the file: &amp;quot; &amp;amp; fsm.FileName &amp;amp; &amp;quot;, Size: &amp;quot; &amp;amp; sizeInKB &amp;amp; &amp;quot; KB.  Would you like to receive this file?&amp;quot;, &amp;quot;File Upload&amp;quot;, MessageBoxButton.OKCancel) = MessageBoxResult.OK Then                bytesReceived = New List(Of Byte)(CInt(Fix(fsm.TotalBytes)))                fileNameReceiving = fsm.FileName                ...            Else                fileDuplexService.SendToServiceAsync(New SendToService(New FileDenyMessage()))            End If        ElseIf TypeOf e.request.msg Is FileTransferBytesMessage Then            If bytesReceived Is Nothing Then                Return            End If            Dim fm As FileTransferBytesMessage = CType(e.request.msg, FileTransferBytesMessage)            bytesReceived.AddRange(fm.Bytes)            ...        ElseIf           ...    End IfEnd Sub


&amp;nbsp; 
When the file is complete, the user will be presented with two buttons.&amp;nbsp; One button will allow the user to save, and the other will allow the user to discard/ignore the file.&amp;nbsp; If the user chooses to save, a
SaveFileDialog is created, and we use the filename to assign the default extension and filter so that when the user saves the file, no extension needs to be typed in.&amp;nbsp; Once the dialog appears and the user enters the file name, the bytes will
 be written to disk.&amp;nbsp; Finally we send a message back to the server which will notify the sender that user has done something with the file.&amp;nbsp; During file send operations, the Send File button is disabled, and becomes re-enabled once a file has been received,
 cancelled, or denied. 
C# 

private void btnSaveFile_Click(object sender, RoutedEventArgs e){    SaveFileDialog sfd = new SaveFileDialog();    string extension = GetExtension(fileNameReceiving);    sfd.DefaultExt = extension;    sfd.Filter = extension &amp;#43;  &amp;quot; Files|&amp;quot; &amp;#43; extension;    if (sfd.ShowDialog() == true)    {        using (Stream fsx = sfd.OpenFile())        {            byte[] fBytes = bytesReceived.ToArray();            fsx.Write(fBytes, 0, fBytes.Length);            fsx.Close();        }        fileDuplexService.SendToServiceAsync(new SendToService(new FileReceivedMessage()));        UIState = UIState.Chat;        btnSendFile.IsEnabled = true;    }}


&amp;nbsp; 
VB 

Private Sub btnSaveFile_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)    Dim sfd As New SaveFileDialog()    Dim extension As String = GetExtension(fileNameReceiving)    sfd.DefaultExt = extension    sfd.Filter = extension &amp;amp; &amp;quot; Files|&amp;quot; &amp;amp; extension    If sfd.ShowDialog() = True Then        Using fsx As Stream = sfd.OpenFile()            Dim fBytes() As Byte = bytesReceived.ToArray()            fsx.Write(fBytes, 0, fBytes.Length)            fsx.Close()        End Using        fileDuplexService.SendToServiceAsync(New SendToService(New FileReceivedMessage()))        UIState = UIState.Chat        btnSendFile.IsEnabled = True    End IfEnd Sub


&amp;nbsp;
Conclusion
Overall, the application does what I set out for it to.&amp;nbsp; It allows a user to send a file to another user and even does basic chat.&amp;nbsp; There is definitely a lot of room for improvement, and some general additions that can make this more robust.&amp;nbsp; Right now we
 keep a list of connections, but never do basic pinging to see if the clients are still there.&amp;nbsp; The only way to know if a client has disconnected is when a message fails, or when the user decides to hit the disconnect button. Better maintenance of this list
 is needed.&amp;nbsp; The file bytes are basically being stored in memory, which is why i set a file size limit, but I&#39;m sure with things like Silverlight local storage, we can increase the limit.&amp;nbsp;
 
Thanks
I would like to thank Brian Peek for taking the time to review my article and test the code. 
Additional Notes
The ASP.NET project requires a file called System.ServiceModel.PollingDuplex.dll to be added as a reference.&amp;nbsp; Somewhere between Silverlight 3 Beta and Silverlight 3 RTW, the file was no longer available via the basic add .NET reference link.&amp;nbsp; In order to
 add the file, I had to browse for it in %Program Files%\Microsoft SDKs\Silverlight\v3.0\Libraries\Server.&amp;nbsp; For 64 bit users, it will be the
Program Files (x86) folder.&amp;nbsp;  
For ease of use, I used a static port (9797) for this project. When deploying to a server, you must rename all references of http://localhost:9797 in the Silverlight project.&amp;nbsp; This will remain true until the config file is supported.
 
The user interface uses the Silverlight Toolkit TwilightBlue theme.&amp;nbsp; For more information about this,&amp;nbsp; see

http://www.codeplex.com/Silverlight 
</description>
	<link></link>
	<language>en</language>
	<pubDate>Mon, 20 May 2013 14:05:17 GMT</pubDate>
	<lastBuildDate>Mon, 20 May 2013 14:05:17 GMT</lastBuildDate>
	<generator>Rev9</generator>
	<item>
		<title>Re: Silverlight 3 File Transfer Application</title>
		<description>
			<![CDATA[ <p>cool application.. works very nicely.. user interface also looking good.. thanks for the project.. </p><p>posted by senthilnathan sk</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c633876336000000000</link>
		<pubDate>Fri, 04 Sep 2009 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c633876336000000000</guid>
		<dc:creator>senthilnathan sk</dc:creator>
	</item>
	<item>
		<title>Re: Silverlight 3 File Transfer Application</title>
		<description>
			<![CDATA[ <p>If I understand this correctly the file you are transferring passes through the server. Any ideas on how to make this a true P2P transfer?</p><p>posted by Eisen626</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c633934260000000000</link>
		<pubDate>Tue, 10 Nov 2009 05:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c633934260000000000</guid>
		<dc:creator>Eisen626</dc:creator>
	</item>
	<item>
		<title>Re: Silverlight 3 File Transfer Application</title>
		<description>
			<![CDATA[ <p>error <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-6.gif?v=c9' alt='Sad' /> : Cannot register duplicate Name 'UIStateConv' in this scope.</p><p>&nbsp; at System.Windows.NameScope.RegisterName(String name, Object scopedElement)</p><p>&nbsp; at Microsoft.Expression.DesignModel.InstanceBuilders.ClrObjectInstanceBuilder.ModifyValue(IInstanceBuilderContext context, ViewNode target, IProperty propertyKey, Object value, PropertyModification modification)</p><p>&nbsp; at Microsoft.Expression.DesignModel.InstanceBuilders.ClrObjectInstanceBuilder.UpdateProperty(IInstanceBuilderContext context, ViewNode viewNode, IProperty propertyKey, DocumentNode valueNode) ... please help me <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-6.gif?v=c9' alt='Sad' /> my mail is : bahno77@gmail.com ... thank you </p><p>posted by bahno77</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634113936000000000</link>
		<pubDate>Sun, 06 Jun 2010 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634113936000000000</guid>
		<dc:creator>bahno77</dc:creator>
	</item>
	<item>
		<title>Re: Silverlight 3 File Transfer Application</title>
		<description>
			<![CDATA[ <p>@bahno77 is this from the source or the physical app itself? &nbsp;I need more to go on. &nbsp;If it is from within Visual Studio, did you alter the program at all?</p><p>posted by Clint</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634120848000000000</link>
		<pubDate>Mon, 14 Jun 2010 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634120848000000000</guid>
		<dc:creator>Clint</dc:creator>
	</item>
	<item>
		<title>Re: Silverlight 3 File Transfer Application</title>
		<description>
			<![CDATA[ <p>@bahno77 &lt;SLFileSender:UIStateConverter x:Key=&quot;UIStateConv&quot; /&gt;</p><p>x:Name is causing it, should be a Key</p><p>I'll get this corrected in the project.</p><p>posted by Clint</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634123440000000000</link>
		<pubDate>Thu, 17 Jun 2010 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634123440000000000</guid>
		<dc:creator>Clint</dc:creator>
	</item>
	<item>
		<title>Re: Silverlight 3 File Transfer Application</title>
		<description>
			<![CDATA[ <p>@Coding4Fun Hello, it is from source here is screenshot : <a rel="nofollow" target="_new" href="http://yfrog.com/0aerrnp">http://yfrog.com/0aerrnp</a> .... on designer it saying : Cannot register duplicate Name 'UIStateConv' in this scope. Please help me</p><p>posted by bahno77</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634123440000000000</link>
		<pubDate>Thu, 17 Jun 2010 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634123440000000000</guid>
		<dc:creator>bahno77</dc:creator>
	</item>
	<item>
		<title>Re: Silverlight 3 File Transfer Application</title>
		<description>
			<![CDATA[ <p>Did you open up the service reference files and change all references from the path: http://localhost:9797/FileSendService.svc &nbsp;to point to your location where you're hosting the web app?</p><p>In the SL project, look under Service References folder, then you'll see the FileSendService. &nbsp;Set VS to show ALL files. &nbsp;This will allow you to expand FileSendService and look and edit the files within. &nbsp;Search for the localhost string above and replace. &nbsp;Aftewards, recompile and upload the new xap file.</p><p>posted by Giovanni</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634124304000000000</link>
		<pubDate>Fri, 18 Jun 2010 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634124304000000000</guid>
		<dc:creator>Giovanni</dc:creator>
	</item>
	<item>
		<title>Re: Silverlight 3 File Transfer Application</title>
		<description>
			<![CDATA[ <p>Hello try my web site here : api.aspone.cz/SLFileSenderTestPage.aspx ... there is original download source code and it won't work <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-6.gif?v=c9' alt='Sad' /> ....</p><p>(it won't make new session try it please as soon as possible , thank you)</p><p>posted by bahno77</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634124304000000000</link>
		<pubDate>Fri, 18 Jun 2010 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634124304000000000</guid>
		<dc:creator>bahno77</dc:creator>
	</item>
	<item>
		<title>Re: Silverlight 3 File Transfer Application</title>
		<description>
			<![CDATA[ <p>@Coding4Fun yeah thank you <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' /> ,but try to download source from link on this site and then upload it to another asp.net site becose i downloaded source and uploaded it and if i created session , nothing happened :/ ... is only two options , first i'm stupid or second somenone uploaded bad code.</p><p>posted by bahno77</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634124304000000000</link>
		<pubDate>Fri, 18 Jun 2010 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634124304000000000</guid>
		<dc:creator>bahno77</dc:creator>
	</item>
	<item>
		<title>Re: Silverlight 3 File Transfer Application</title>
		<description>
			<![CDATA[ <p>@Giovanni , THANK YOU SO MUCH !!! it works <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' />) thank you <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' /></p><p>posted by bahno77</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634131216000000000</link>
		<pubDate>Sat, 26 Jun 2010 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Silverlight-3-File-Transfer-Application#c634131216000000000</guid>
		<dc:creator>bahno77</dc:creator>
	</item>
</channel>
</rss>