Image.FromStream (PostsFile.InputStream) non riesce. (Il parametro non è valido.) (AsyncFileUpload))
-
06-07-2019 - |
Domanda
Sto usando un AsyncFileUpload (AJAX Toolkit) per caricare immagini. Ho un pulsante che gestisce il ridimensionamento dell'immagine. Questo ha funzionato bene per qualche tempo, ma non più ...
protected void BtnUploadImage_Click(object sender, EventArgs e)
{
var imageFileNameRegEx = new Regex(@"(.*?)\.(jpg|jpeg|png|gif)<*>quot;,
RegexOptions.IgnoreCase);
if (!AsyncFileUpload1.HasFile ||
!imageFileNameRegEx.IsMatch(AsyncFileUpload1.FileName))
{
AsyncFileUpload1.FailedValidation = true;
ErrorLabel.Visible = true;
return;
}
ErrorLabel.Visible = false;
var file = AsyncFileUpload1.PostedFile.InputStream;
var img = Image.FromStream(file, false, false);
...
}
Un'altra cosa che trovo strana: se provo un'immagine più piccola di 80kb, funziona ..!
Abbiamo provato a riavviare il server, ma nessuna modifica. Lo stesso codice funziona bene sulla mia macchina. (sentito prima ?? :))
Ho anche provato a salvare il file sul server, quindi a ottenere il file tramite Image.FromFile (), ma poi ho " Impossibile accedere a un file chiuso. "
Come risolverlo?
Soluzione
Mi assicurerei che lo stream sia posizionato all'inizio:
var file = AsyncFileUpload1.FileContent;
file.Seek(0, SeekOrigin.Begin);
var img = Image.FromFile(file);
Seconda cosa da verificare: la requestLengthDiskThreshold
. Se non diversamente specificato, questa impostazione ha un valore predefinito di ... Sì, 80 KB.
Nota: imo non ci dovrebbero essere differenze complessive se si utilizza Image per leggere direttamente il flusso di file o se si utilizza un MemoryStream intermedio (a parte il fatto che in quest'ultimo caso si carica effettivamente il intero file in memoria due volte). In entrambi i casi verrà letto il flusso di file originale, quindi si applicano ancora la posizione del flusso, i diritti CAS, i permessi dei file, ecc.
Nota2: e sì, assicurati che tali risorse siano correttamente smaltite :)
Altri suggerimenti
Questo è corretto, non funzionerà. Il problema è che stai attraversando un confine gestito / non gestito, di recente ho riscontrato lo stesso. Altri problemi sono che lo stream non è direttamente lì e Image.FromStream non ha idea di come gestirlo.
La soluzione è piuttosto semplice: leggi tutto da PostsFile in MemoryStream (usa new MemoryStream ()
) e usa MemoryStream con Image.FromStream
. Questo risolverà il tuo problema.
Assicurati di usare correttamente usando
quando lavori con Image
, Graphics
e Stream
. Tutti implementano IDisposable e in un ambiente ASP.NET, non usando correttamente i blocchi usando
, possono e porteranno ad un aumento dell'utilizzo della memoria e ad altri effetti collaterali sgradevoli a lungo termine (e app ASP.NET correre molto a lungo!).
La soluzione dovrebbe assomigliare a questa:
using(Stream memstr = new MemoryStream())
{
// copy to a memory stream
Stream uploadStream = AsyncFileUpload1.PostedFile.InputStream;
byte[] all = new byte[uploadStream.Length];
uploadStream.Read(all, 0, uploadStream.Length);
memstr.Write(all, 0, uploadStream.Length);
memstr.Seek(0, SeekOrigin.Begin);
using(Graphics g = Graphics.FromStream(memstr))
{
// do your img manipulation, or Save it.
}
}
Aggiornamento: il problema del confine gestito dall'attraversamento si verifica solo al contrario (utilizzando il flusso di risposta), a quanto pare, non con i flussi di caricamento, ma non ne sono del tutto sicuro.