2

Where do I set HttpContext.Request.GetBufferlessInputStream(true)? I am trying to allow the user to upload files larger than 2GB and obviously I am running into the "maxRequestLength" int type restriction. I have tried to create a StreamReader the following way:

var reader = new StreamReader(HttpContext.Request.GetBufferlessInputStream(true));

But I'm doing it in a controller and I end up getting the following error:

"This method or property is not supported after HttpRequest.Form, Files, InputStream, or BinaryRead has been invoked."

So I'm guessing I have to make this change before the controller method gets called. I've searched stack overflow and many other websites for answers, but all I've found is how to use it not where to use it.

Thank you for your time and helping me out with this.

BlueCardinal
  • 153
  • 3
  • 12

1 Answers1

1

You are going to have to implement your logic in an HttpModule - see this similar question: How should I use HttpRequest.GetBufferlessInputStream?

Update - actually you are better off writing your own HttpHandler instead of a Module

Using GetBufferlessInputStream is basically telling ASP.NET that you are going to handle the entire request, instead of only a portion of it. As you've seen when you use this in a module, after your module completes, the request continues through the remainder of the request pipeline, and ASP.NET is going to expect to be able to read part of the input.

By writing your own HttpHandler, you are responsible for the entirety of the processing - so this would only be for handling the large upload.

I found a link with a sample that looks pretty relevant for you https://blogs.visoftinc.com/2013/03/26/streaming-large-files-asynchronously-using-net-4-5/

Chris Riccio
  • 573
  • 3
  • 11
  • Cool. Thanks for the info. I created an HttpModule, but now I have a different issue I outline here: https://stackoverflow.com/questions/48776028/this-method-is-not-supported-after-httprequest-getbufferlessinputstream-has-been?noredirect=1&lq=1 Think you could help me out with that? – BlueCardinal Feb 15 '18 at 19:32
  • That worked really well. Thanks. But now I have a different problem. How would I extract the file I post so I can save it. I don't want to write it to a text file so StreamWriter isn't what I want to use. Before this I was just appending the file to formdata in Jquery like the first answer to this question: [link](https://stackoverflow.com/questions/29910490/how-to-upload-file-using-javascript) and then I was accepting it as a HttpPostedFileBase in my controller. – BlueCardinal Feb 21 '18 at 14:14
  • I've read here [link](https://stackoverflow.com/questions/17602845/post-error-either-binaryread-form-files-or-inputstream-was-accessed-before-t) how 'BinaryRead()', 'Form', 'Files', and 'InputStream' won't cooperate with 'GetBufferlessInputStream()' so I'm kind of lost how to extract the file from the Request so I can save it. Thanks! – BlueCardinal Feb 21 '18 at 14:14
  • You will get a Stream object from GetBufferlessInputStream - that stream represents the uploaded file. Depending upon the content type of the file, you will need to decide how to write it. If it's just a large text file, you should be able to create a StreamWriter and pass it the Stream. If it's a large binary file, you should create a BinaryWriter and pass it the Stream. – Chris Riccio Feb 21 '18 at 17:37
  • So the file is a .db file so I would use a StreamWriter but doing something similar to [this](https://stackoverflow.com/questions/11850564/convert-db-to-binary) doesn't work because 2GB will be too big for int.MaxValue. I tried creating an extention method similar to [this](https://stackoverflow.com/questions/8613187/an-elegant-way-to-consume-all-bytes-of-a-binaryreader/8613300#8613300) but MemoryStream's capacity is of type Int....... – BlueCardinal Feb 22 '18 at 21:09
  • Hello? You wouldn't have any further suggestions would you? – BlueCardinal Feb 26 '18 at 18:13
  • I would consider a .db file to be a binary file and open the input stream with a BinaryReader and output with a BinaryWriter – Chris Riccio Feb 26 '18 at 22:12
  • Right Sorry. I meant that the file was a .db file so I would use the BinaryWriter. Not the StreamWriter. The problem with reading it with a BinaryReader is that BinaryReader's capacity is of type 'int' so 2GB would be it's max. – BlueCardinal Feb 27 '18 at 15:27
  • Don't read it all in at once - you are going to run into memory issues - you should be able to ReadBytes in chunks and Write those chunks - "writer.Write(reader.ReadBytes(1024));" – Chris Riccio Feb 27 '18 at 17:32
  • So that worked, but the file turned out to be unreadable. It was also 247 bytes larger than the original file that was uploaded. I inspected the stream object from GetBufferLessInputStream and it was also 247 bytes larger than the orginal file. So I'm guessing more than just the file is being sent in the Request and I need to strip that part out.....any ideas how to do that? – BlueCardinal Feb 28 '18 at 19:49
  • Assuming you are uploading using a form with encoding type of multi-part/form-data, there will be extra information that you will have to parse out before starting to write the buffer. Since you're using GetBufferlessInputStream you lose out on the friendly helpers that take care of it for you. There is good discussion [here](https://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean) on what exactly the browser sends. Most of the data is the same length each time, but the filename is included, so the size will change (so you can't just skip the first 247 bytes) – Chris Riccio Feb 28 '18 at 20:22
  • Actually I got it working. Thank you so much for all your help with this! – BlueCardinal Mar 01 '18 at 17:50