2009-10-23 14 views
5

Ich verwende ein AsyncFileUpload (AJAX Toolkit), um Bilder hochzuladen. Ich habe einen Button, mit dem die Bildgrößenänderung gehandhabt wird. Dies gearbeitet haben seit einiger Zeit in Ordnung, aber nicht mehr ...Image.FromStream (PostedFile.InputStream) schlägt fehl. (Der Parameter ist nicht gültig.) (AsyncFileUpload))

protected void BtnUploadImage_Click(object sender, EventArgs e) 
{ 
    var imageFileNameRegEx = new Regex(@"(.*?)\.(jpg|jpeg|png|gif)$", 
     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); 

... 
} 

Eine andere Sache, die ich komisch finde: Wenn ich ein Bild versuchen, die als 80kb kleiner ist es funktioniert ..!

Wir haben versucht, den Server neu zu starten, aber keine Änderung. Derselbe Code läuft auf meinem Rechner einwandfrei. (gehört das vorher ?? :))

Ich habe auch versucht, die Datei auf dem Server zu speichern, dann die Datei durch Image.FromFile() zu bekommen, aber dann bekomme ich "Kann nicht auf eine geschlossene Datei zugreifen."

Wie löst man das?

+0

Es gibt Code fehlt in Ihrem Snippet. –

+0

@Joseph, ich denke, dass nur das Hinzufügen der Endstrebe an der Funktion falsch ist, kann es nicht einfach dort aufhören, die 'img' Variable wird nicht verwendet. –

+0

Dachte nicht der Rest war relevant, was nach Image passiert.FromStream() wird trotzdem nicht ausgeführt. –

Antwort

7

Ich würde sicherstellen, dass der Strom am Anfang positioniert ist:

var file = AsyncFileUpload1.FileContent; 
file.Seek(0, SeekOrigin.Begin); 

var img = Image.FromFile(file); 

Zweite, was zu überprüfen: the requestLengthDiskThreshold Einstellung. Wenn nicht angegeben, hat diese Einstellung den Standardwert ... ja, 80 KB.

Hinweis: imo sollte es keine Gesamt Unterschied, ob Sie Bild verwenden, um die Datei-Stream direkt zu lesen oder wenn Sie einen Zwischenmemorystream (außer der Tatsache, dass Sie tatsächlich im letzteren Fall die gesamte Datei in den Speicher geladen zweimal). In beiden Fällen wird der ursprüngliche Dateistream gelesen, daher gelten die Stream-Position, CAS-Rechte, Dateiberechtigungen usw. weiterhin.

Hinweis 2: und ja, mit allen Mitteln sicherstellen, sind diese Mittel ordnungsgemäß entsorgt :)

+1

Danke, das hat wie ein Charme gearbeitet. Ich hatte die HttRuntime-Einstellungen angeschaut, aber irgendwie die Einstellung von requestLengthDiskThreshold total übersehen. :( Noch einmal Sie sparen den Tag: D –

+0

@PeterLillevold, wie dies ohne Ajax Toolkit –

+0

erreichen @ HeemanshuBhalla erreichen was? Sie müssen genauer hier sein, meine Antwort gilt nicht nur für ATK. Fragen Sie nach Bildupload im Allgemeinen? Wenn ja, suchen Sie nach vorhandenen QAs hier auf SO, oder stellen Sie eine neue Frage. –

1

Das ist richtig, es wird nicht funktionieren. Das Problem ist, dass Sie eine verwaltete/nicht verwaltete Grenze überschreiten. Ich bin kürzlich auf dasselbe gestoßen. Andere Probleme sind, dass der Stream nicht direkt da ist und der Image.FromStream keine Ahnung hat, wie er damit umgehen soll.

Die Lösung ist recht einfach: Lesen Sie alles von PostedFile in einen MemoryStream (verwenden Sie einfach new MemoryStream()) und verwenden Sie den MemoryStream mit der Image.FromStream. Dies wird dein Problem lösen.

Stellen Sie sicher, dass using ordnungsgemäß verwendet wird, wenn Sie mit Image, Graphics und Stream s arbeiten. Alle von ihnen implementieren die IDisposable und in einer ASP.NET-Umgebung, die using Blöcke nicht richtig verwendet, kann und wird auf lange Sicht führen zu erhöhten Speicherauslastung und andere fiese Nebeneffekt führen (und ASP.NET-Anwendungen laufen sehr lange!).

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. 
    } 
} 

Update::

so etwas wie dies sollte die Lösung aussehen die Überquerung geschafft Grenze Problem tritt nur in der umgekehrten (Response-Stream verwendet wird), so scheint es, nicht mit Hochladen von Strömen, aber ich bin mir nicht ganz sicher.

+0

Könnten Sie bitte ein Beispiel geben, wie Sie alle Bytes im Speicherstrom lesen können? –

+0

Hinweis: Es ist nicht garantiert, dass der 'Read' funktioniert. Wenn nicht, enthält der Rückgabewert die Anzahl der Bytes, die tatsächlich gelesen wurden. Sie können Ihren Code robuster machen, indem Sie immer den Rückgabewert von 'Read()' überprüfen oder eine Schleife erstellen, bis alle Bytes gelesen sind. – Abel

+0

Versucht dies: string imageID; \t \t verwenden (var mStream = new Memory()) { \t \t \t var uploadStream = AsyncFileUpload1.PostedFile.InputStream; \t \t var all = neues Byte [uploadStream.Length]; \t \t uploadStream.Read (alle, 0, (int) uploadStream.Length); \t \t mStream.Write (alle, 0, (int) uploadStream.Length); \t \t mStream.Seek (0, SeekOrigin.Begin); \t \t verwenden (var img = Image.FromStream (mStream)) \t \t { \t \t \t imageId = ImageCreation.SaveImage (img, true); \t} \t} Aber ich bekomme {"Parameter ist nicht gültig."}, Immer noch auf dem Image.FromStream. (Jetzt sogar auf dem lokalen Rechner) –

Verwandte Themen