Skip to main content
Home Forums Silverlight Programming Programming with .NET - General SL & WCF - 6MB upload limit?!
19 replies. Latest Post by rajesh shirpuram on August 3, 2008.
(0)
pcroke
Member
9 points
13 Posts
07-28-2008 2:44 AM |
I've written an upload web service for transfering files to a web server (mostly as something to play with), and tested the WCF service against a standard WinForms app - This worked as expected transferring large files w/o issues. I then added a simple SL client (openfile dialog + one label!) and tried the same test; This gave me a 'System.ExecutionEngineException' exception, and when I looked at the transferred file size I managed to get 6mb regardless of type of file or file size. Files under 6mb transferred with no issue.
I kinda think I'm missing something obvious, but can't spot it. Anyone had something similar, or can offer any suggestions?
Thanks.
rajesh s...
Contributor
2314 points
505 Posts
07-28-2008 2:54 AM |
you need to up the buffer in the application and insert the following in your web.config:<httpRuntime maxRequestLength="8192" />
07-28-2008 3:01 AM |
Thanks for the response; This seems to cause the problem even faster!
The service only transfers 8k chunks at a time ( keeps transfering until the entire file has been uploaded), so I think this should have had no effect?
07-28-2008 3:11 AM |
What is maxBufferSize setting in your web.config.?
07-28-2008 3:15 AM |
65536 (This is the default).
07-28-2008 6:10 AM |
hmmm...Let me develop a sample app and get back to you.
07-28-2008 6:54 AM |
Thanks - Appreciate your time.
sladapter
All-Star
17445 points
3,173 Posts
07-28-2008 11:11 AM |
You need to do the following configuration change if your file string size exceeding 8000 chars:
1) Under the tool menu find WCF service configuration Editor and open it. Open the Web.config under your Web project that host your service:
Now you should be upload a file up to 4MB. 3) If you hit limit again. Then you need to increas the httpRuntime maxRequestLength setting in your Web config. The default valus 4096(K) was set in machine.config. You need to increase that value such as 8192 or higher. <system.web> ... <httpRuntime maxRequestLength="8192" /> // Default was 4096(K) in machine.config. You can change it to a larger number</system.web> 4) If you allow file size more than 30 MB to be uploaded, then you might hit another limit again. Then you need to break your file into smaller chunks then pass them back one chunk at a time. If you need this. See this thread: http://silverlight.net/forums/p/19756/67535.aspx#67535
07-28-2008 2:29 PM |
Thanks - I'm already transferring the file in chunks so I'm a bit confused! I'll take a look at your sample and see if I can figure out what I'm doing wrong.
07-28-2008 2:33 PM |
If your file size is not that big (> 30MB), by changing the configuration alone should solve your problem.
07-29-2008 12:20 AM |
sladapter is right. Even i tried and created sample project it works fine .....
can you post your demo code here?
07-29-2008 3:00 AM |
Thanks to you both for your comments. The main difference between my code and sladapters is that I keep the filestream open and read as required whereas sladapter reads the entire file into memory. I'm guessing that the problem is actually keeping the stream open for the entirety of the transfer rather than an size limit. I'm going to change my code to reflect this and test, but I need to do some "real" work first! ;-).
Thanks again the help.
07-29-2008 3:09 PM |
pcroke or anyone wants to do file upload:
Yi-Lun Luo - MSFT at this thread http://silverlight.net/forums/t/20788.aspx showed how to use WebClient.OpenWriteAsync. I tested using WCF and using WebClient.OpenWriteAsync + HttpHandler to do file upload and found using WebClient.OpenWriteAsync is much a efficient way than using WCF call. You do not have to mess up with configuration, and you do not have to break files in chunks even the file size is > 30 MB. It is much faster than using WCF call for uploading large files.
Following is the code sample in case any one want to do it this way:
Add a Generic HttpHander called FileUpload.ashx to your Web Project:
[WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class FileUpload : IHttpHandler { public void ProcessRequest(HttpContext context) { HttpRequest request = context.Request; HttpResponse response = context.Response; HttpServerUtility server = context.Server; string fileName = context.Request.Params["filename"]; if (!string.IsNullOrEmpty(fileName)) { using(Stream inputStream = request.InputStream) {
string folder = Path.GetFullPath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "FileStore"));// assume using filestore folder for uploaded files. if (!System.IO.Directory.Exists("FileStore")) System.IO.Directory.CreateDirectory(folder); using (FileStream fs = new FileStream(folder + @"\" + filename, FileMode.OpenOrCreate)) { byte[] fileContent = new byte[inputStream.Length]; inputStream.Read(fileContent, 0, fileContent.Length); fs.Write(fileContent, 0, fileContent.Length); fs.Flush(); } } response.Clear(); response.End(); } } public bool IsReusable { get { return false; } } }
byte[] fileContent = System.Text.Encoding.UTF8.GetBytes(YourFileContentString);
WebClient wc = new WebClient();wc.OpenWriteCompleted +=new OpenWriteCompletedEventHandler(wc_OpenWriteCompleted);Uri u = new Uri(Application.Current.Host.Source, "../FileUpload.ashx/?filename=" + FileName);wc.OpenWriteAsync(u, null, fileContent);
void wc_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e) { if (e.Error == null) {
byte[] fileContent = e.UserState as byte[]; Stream outputStream = e.Result; outputStream.Write(fileContent, 0, fileContent.Length); outputStream.Close(); } } }
07-30-2008 3:21 AM |
I'd seen something similar to this, but I decided against it for a couple of reasons - Would be interested if you think they are valid!
1. I already have authentication schemes in place for WCF, and wanted to reuse them
2. The WCF route seemed more adaptable; for instance it can deal with losing the network connection and resuming the download, but I don't think that the filehandler version can.
3. I want to be able to change the target of the store easily (e.g. database) w/o storing the file on the web server as an intermediate phase. I know I should be able use the file handler version to that by implementing Stream to write to my database, but that feels like a lot of hard work and I can just re-implement the WCF interface to make other targets work.
07-30-2008 9:12 AM |
Of course they are all valid. Everybody should choose the best way to suit them. If you are after performance, reducing bandwidth usage when passing data and don't want to mess up with the service configuration and break files into chunks, using WebClient.OpenWrite + HttpHandler might be a better choice at this point. But if you don't care about those, and want to take the other advantages of WCF provide, certainly that is also valid.
Hopefully, Silverlight will support stream later so we should be able to achieve the same performance using WCF as that using HttpHandler.
Ozzy1
22 points
16 Posts
08-03-2008 2:45 PM |
I seem to be having a similar problem. I too am using a WCF to upload a file in chunks, and I also get an ExecutionEngineException. I have increased the size limits as you suggested, but the exception still occurs exactly as before. In my case, the files are smaller (less than 3MB), which makes me think this problem is not related to file size. The exception happens 90% of the time; however, if it succeeds, then it never fails again during that session. If I shut down the web browser, delete the uploaded files and restart (thus starting a new session), then it usually fails. The number of files that I can successively upload before the exception occurs varies -- usually after 2 or 3 files -- and it always seems to fail mid-file, not when opening or closing a file. The chunk size I am using is 16K, so the WCF is called about 175 times per file.
This problem occurs on IE7, Safari and FF. I am using VS2008 ver 9.0.30428.1 SP1Beta, .NET 3.5 SP1, IIS 7.0.6000.16386.
08-03-2008 3:03 PM |
For 3MB file, you really have no need to break the file into chunks. Configuration change should work. Breaking files into chunks is really not the best solution, it's the last resort when we have no choice when the file size is too large (> 30 MB) if using WCF. Think about it, if one chunk fails for whatever reason, the whole operation is failed.
Even I had a code to do it http://www.2shared.com/file/3535556/a86cad70/SilverlightUpload.html, But I never like the idea. That's why now I'm prefer using HTTPHandler to do file upload than WCF.
I don't know what cause your problem. But if you want use WCF your can try my code in the above link and see if you get the same problem.
08-03-2008 9:57 PM |
Thanks for the feedback and the code. 3 MB is just the size I am using for testing at the moment, but I will be supporting much larger files. One of the advantages of chunking is that I can show upload progress to the user. I upload multiple files simultaneously, so upload progress feedback is important. I tried two HTTPHandler solutions, one where I uploaded the entire file and one where I chunked the file. I didn't see a way to show upload progress when uploading the entire file at once -- if you can show how to do this, I would be very interested.
As for the exception I was experiencing, I found that it happened when the chunk size was 16 KB or less, regardless of how many files I was uploading at the same time. However, when I increased the chunk size to 64 KB or 128 KB, the exception is no longer thrown -- there were no other code changes other than the chunk size. That makes me a little nervous.
08-03-2008 10:24 PM |
If you use WebClient + HttpHandler, you can use wc.UploadStringAsync call. WebClient has UploadProgressChanged event. It should tell you the upload progress:
WebClient wc = new WebClient(); wc.UploadProgressChanged+=new UploadProgressChangedEventHandler(wc_UploadProgressChanged); wc.UploadStringAsync(HTTPHanlderUri, data);
void wc_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e) {
// Here you can get e.ProgressPercentage }
08-03-2008 10:27 PM |
Thanks sladapter for sharing the file upload code.