Znalazłem w końcu rozwiązanie. Nie wiem czy poprawne. Opiszę je dla "potomności" :) i w celu weryfikacji przez szanownych forumowiczów.
1. W Gloabal.asax.cs dodaję
protected void Session_Start(Object sender, EventArgs e)
{
Session["init"] = 0;
}
Umożliwia mi to pobranie dla każdej sesji unikatowego ID: Session.SessionID
2. Wykorzystałem plugin plupload. Ale nie pobrałem go z oryginalnej strony tylko z https://github.com/RickStrahl/Westwind.plUploadHandler
Potrzebne są następujące plik Java Script:
- plupload.full.js
- plupload.full.mini.js
- jquery.plupload.quote.js
- jquery.plupload.quote.mini.js
Oraz plik css:
- jquery.plupload.quote.css
3. Do formularza dodaję
<div id="uploader">
<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
4. Do mojego pliku java script dodaję funkcję obsługującą plugin plupload:
$("#uploader").pluploadQueue({
runtimes: 'html5,silverlight,flash,html4',
url: 'home/upload',
max_file_size: '10mb',
chunk_size: '1mb',
unique_names: false,
filters: [
{ title: "Images", extensions: "jpg,jpeg,bmp,gif,png" },
{ title: "Archives", extensions: "zip,rar,7z,tar,tg" },
],
rename: true,
flash_swf_url: '/js/plupload.flash.swf',
silverlight_xap_url: '/js/plupload.silverlight.xap',
preinit: {
Init: function() {
$('#uploader_container').removeAttr("title");
}
}
});
5. oraz funkcję wysyłającą pliki przed przesłaniem formularza (Nie jestem pewny tej funkcji, ale działa):
$("#form-complaint").submit(function(event)
{
var uploader = $('#uploader').pluploadQueue();
if (uploader.files.length > 0) {
uploader.bind('StateChanged', function() {
if (uploader.files.length === (uploader.total.uploaded + uploader.total.failed)) {
$(this).submit();
}
});
uploader.start();
return true;
}
else {
// $(this).submit();
return true;
}
return false;
});
6. No i pozostaje utworzenie metody w kontrolerze do pobierania plików. Metoda ta zostaje wywołana oddzielnie dla każdego przesłanego pliku. Kod javascript prześle najpierw pliki a później dane z formularza.
[HttpPost]
public ActionResult Upload(int? chunk, string name)
{
var session = Session.SessionID;
var fileUpload = Request.Files[0];
var uploadPath = Server.MapPath("~/App_Data/"+session);
if (!Directory.Exists(uploadPath))
Directory.CreateDirectory(uploadPath);
chunk = chunk ?? 0;
string uploadedFilePath = Path.Combine(uploadPath, name);
using (var fs = new FileStream(uploadedFilePath, chunk == 0 ? FileMode.Create : FileMode.Append))
{
var buffer = new byte[fileUpload.InputStream.Length];
fileUpload.InputStream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, buffer.Length);
}
return Content("Success", "text/plain");
}
7. W metodzie odbioru danych z formularza wykorzystuję Session.SessionID. Jest ono takie samo jak poprzednie z metody Upload.
Wydaje mi się, że to rozwiązanie działa. Zastanawiam się tylko czy jest prawidłowe. Czy jednak nie powinienem dla każdej sesji wstawiać np. do Session["MojUnikatowyId"] = coś_unikatowego i z tego korzystać w metodzie Upload oraz metodzie odbioru danych z formularza.
8. Warto także dodać do pliku css ukrycie przycisku Send files z pluginu plupload:
.plupload_button.plupload_start {
display: none!important;
}
Oczywiście jeszcze pozostaje kwestia powiązania danych z formularza z plikami. Ale one są już w folderze o unikatowej (mam nadzieję) nazwie, którą mogę przekazać do procedury zapisującej dane z formularza.
Proszę szanownych forumowiczów o komentarze czy to rozwiązanie jest prawidłowe.