The Http Multipart Parser does it exactly what it claims on the tin: parses multipart/form-data. This particular parser is well suited to parsing large data from streams as it doesn't attempt to read the entire stream at once and procudes a set of streams for file data.
Simply add the HttpMultipartParser project to your solution and reference it in the projects you want to use it in.
There is also a NuGet package provided.
The parser was built and tested for NET 4.0. Versions lower then this may work but are untested.
- Create a new MultipartFormDataParser with the stream containing the multipart/form-data.
- Access the data through the parser.
- Create a new StreamingMultipartFormDataParser with the stream containing the multipart/form-data
- Set up the ParameterHandler and FileHandler delegates
- Call parser.Run()
- The delegates will be called as data streams in.
// stream: -----------------------------41952539122868 Content-Disposition: form-data; name="username" example -----------------------------41952539122868 Content-Disposition: form-data; name="email" example@data.com -----------------------------41952539122868 Content-Disposition: form-data; name="files[]"; filename="photo1.jpg" Content-Type: image/jpeg ExampleBinaryData012031203 -----------------------------41952539122868-- // ===== Simple Parsing ==== // parse: var parser = new MultipartFormDataParser(stream); // From this point the data is parsed, we can retrieve the // form data using the GetParameterValue method. var username = parser.GetParameterValue("username"); var email = parser.GetParameterValue("email") // Files are stored in a list: var file = parser.Files.First(); string filename = file.FileName; Stream data = file.Data; // ==== Advanced Parsing ==== // parse: var parser = new StreamingMultipartFormDataParser(stream); parser.ParameterHandler += parameter => DoSomethingWithParameter(parameter); parser.FileHandler += (name, fileName, type, disposition, buffer, bytes) => { // Write the part of the file we've recieved to a file stream. (Or do something else) filestream.Write(buffer, 0, bytes); } // stream: -----------------------------41952539122868 Content-Disposition: form-data; name="checkbox" likes_cake -----------------------------41952539122868 Content-Disposition: form-data; name="checkbox" likes_cookies -----------------------------41952539122868-- // ===== Simple Parsing ==== // parse: var parser = new MultipartFormDataParser(stream); // From this point the data is parsed, we can retrieve the // form data from the GetParameterValues method var checkboxResponses = parser.GetParameterValues("checkbox"); foreach(var parameter in checkboxResponses) { Console.WriteLine("Parameter {0} is {1}", parameter.Name, parameter.Data) } // stream: -----------------------------41111539122868 Content-Disposition: form-data; name="files[]"; filename="photo1.jpg" Content-Type: image/jpeg MoreBinaryData -----------------------------41111539122868 Content-Disposition: form-data; name="files[]"; filename="photo2.jpg" Content-Type: image/jpeg ImagineLotsOfBinaryData -----------------------------41111539122868-- // ===== Simple Parsing ==== // parse: var parser = new MultipartFormDataParser(stream); // Loop through all the files foreach(var file in parser.Files) { Stream data = file.Data; // Do stuff with the data. } // ==== Advanced Parsing ==== // parse: var parser = new StreamingMultipartFormDataParser(stream); parser.ParameterHandler += parameter => DoSomethingWithParameter(parameter); parser.FileHandler += (name, fileName, type, disposition, buffer, bytes) => { // Write the part of the file we've recieved to a file stream. (Or do something else) // Assume that filesreamsByName is a Dictionary<string, FileStream> of all the files // we are writing. filestreamsByName[name].Write(buffer, 0, bytes); }; parser.StreamClosedHandler += () { // Do things when my input stream is closed }; Please see LICENSE