Image.FromStream(PostedFile.InputStream)失败。 (参数无效。)(AsyncFileUpload))
我正在使用AsyncFileUpload(AJAX Toolkit)上传图像。 我有一个处理图像大小调整的按钮。 这已经好了一段时间了,但现在不行了……
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); ... }
另一件我觉得很奇怪的事情:如果我尝试的图像小于80kb就可以了。
我们试图重启服务器,但没有改变。 相同的代码在我的机器上运行良好。 (听说之前?? :))
我还尝试将文件保存在服务器上,然后通过Image.FromFile()获取文件,但后来我得到“无法访问已关闭的文件”。
怎么解决这个?
我会确保流在开始时定位:
var file = AsyncFileUpload1.FileContent; file.Seek(0, SeekOrigin.Begin); var img = Image.FromFile(file);
要检查的第二件事: requestLengthDiskThreshold
设置。 除非指定此设置,否则默认值为… yes,80 KB。
注意: imo不管是使用Image直接读取文件流还是使用中间MemoryStream都不应该有整体区别(除了在后一种情况下实际上将整个文件加载到内存中两次的事实)。 无论哪种方式都将读取原始文件流,因此流位置,CAS权限,文件权限等仍然适用。
注2:是的,一定要确保正确处理这些资源:)
这是正确的,它将无法正常工作。 问题是你正在越过托管/非托管边界,我最近遇到了同样的问题。 其他问题是流不直接存在,Image.FromStream不知道如何处理它。
解决方案非常简单:将所有内容从PostedFile读入MemoryStream(只需使用new MemoryStream()
)并将MemoryStream与Image.FromStream
。 这将解决您的问题。
using
Image
, Graphics
和Stream
时,请确保正确使用。 所有这些都实现了IDisposable,并且在ASP.NET环境中,不使用正确using
块,可以并且将导致更长的内存使用和其他令人讨厌的副作用(并且ASP.NET应用程序确实运行很长时间!)。
解决方案应该如下所示:
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. } }
更新:交叉管理边界问题只发生在反向(使用响应流),似乎不是上传流,但我不完全确定。