Image.FromStream(PostedFile.InputStream)失败。 (参数无效。)(AsyncFileUpload))

时间:2009-10-23 17:11:17

标签: c# image asp.net-ajax upload ajaxcontroltoolkit

我正在使用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()获取文件,但后来我得到“无法访问已关闭的文件。”

如何解决这个问题?

2 个答案:

答案 0 :(得分:7)

我会确保流位于开头:

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

var img = Image.FromFile(file);

要检查的第二件事:the requestLengthDiskThreshold设置。除非指定此设置,否则默认值为... yes,80 KB。

注意: imo无论使用Image直接读取文件流还是使用中间MemoryStream,都应该没有整体区别(除了在后一种情况下实际加载了将整个文件存入内存两次)。无论哪种方式都将读取原始文件流,因此流位置,CAS权限,文件权限等仍然适用。

注2:,是的,务必确保妥善处理这些资源:)

答案 1 :(得分:1)

这是正确的,它不起作用。问题是你正在越过托管/非托管边界,我最近遇到了同样的问题。其他问题是流不直接存在,Image.FromStream不知道如何处理它。

解决方案非常简单:将所有内容从PostedFile读入MemoryStream(只需使用new MemoryStream())并将MemoryStream与Image.FromStream一起使用。这将解决您的问题。

使用usingImageGraphics时,请务必正确使用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.
    }
}

更新:跨越管理边界问题只发生在反向(使用响应流),似乎不是上传流,但我不完全确定。