Overview
I have a Microsoft Word Add-In, written in VBA (Visual Basic for Applications), that compresses a document and all of it’s related contents (embedded media) into a zip archive. After creating the zip archive it then turns the file into a byte array and posts it to an ASMX web service. This mostly works.
Issues
The main issue I have is transferring large files to the web site. I can successfully upload a file that is around 40MB, but not one that is 140MB (timeout/general failure).
A secondary issue is that building the byte array in the VBScript Word Add-In can fail by running out of memory on the client machine if the zip archive is too large.
Potential Solutions
I am considering the following options and am looking for feedback on either option or any other suggestions.
Option One
Opening a file stream on the client (MS Word VBA) and reading one “chunk” at a time and transmitting to ASMX web service which assembles the “chunks” into a file on the server.
This has the benefit of not adding any additional dependencies or components to the application, I would only be modifying existing functionality. (Fewer dependencies is better as this solution should work in a variety of server environments and be relatively easy to set up.)
Question:
- Are there examples of doing this or any recommended techniques (either on the client in VBA or in the web service in C#/VB.NET)?
Option Two
I understand WCF may provide a solution to the issue of transferring large files by “chunking” or streaming data. However, I am not very familiar with WCF, and am not sure what exactly it is capable of or if I can communicate with a WCF service from VBA. This has the downside of adding another dependency (.NET 3.0). But if using WCF is definitely a better solution I may not mind taking that dependency.
Questions:
- Does WCF reliably support large file transfers of this nature? If so, what does this involve? Any resources or examples?
- Are you able to call a WCF service from VBA? Any examples?
I ended up implementing option one referenced in the original question.
I “chunk” the file in VBA and transfer each “chunk” to the web service. I based the VBA portion of the solution on the code found here: Copy Large File by Chunk with Progress Notification. Instead of copying to the file system, however, I send it to the server.
The Code: VBA Land
Here is the (fugly) VBA code that creates the file chunks:
Here is the referenced VBA method that uploads the chunks to the server:
The Code: C# ASMX Web Service
Now, on the server side, the web service method accepts a few important parameters.
file (each chunk has the same file
name)
of each chunk
(used in conjunction with fileName
to provide unique ordered partial
files on the file system)
go ahead and merge all the “chunks”
and clean up after yourself” flag.
int index and bool isLastChunk. With this context provided from the VBA world, I know enough to save each of these file chunks and then combine them when the isLastChunk flag is true.
Here is the C# code that writes each incoming chunk the the file system:
Here is the C# code to merge all of the zip file “chunks”: