GDI+发生了一般性错误。

11
[ExternalException (0x80004005): A generic error occurred in GDI+.]
   IpitchitImageHandler.Data.ImageRepository.AddNewTempImage(Stream image, String extension, Guid PageId, Guid ImageId, ImageTransformCollection toDoTransforms) +1967
   IpitchitImageHandler.Data.ImageRepository.AddNewTempImage(Stream image, String extension, Guid PageId, Guid ImageId) +85
   IpitchitWeb.Sell.Controls.UploadImagesSubstep.UploadImages(Object sender, EventArgs e) in F:\Documents and Settings\Vjeran\My Documents\Visual Studio 2008\Projects\Ipitchit\IpitchitWeb\Sell\Controls\UploadImagesSubstep.ascx.cs:88
   System.Web.UI.WebControls.LinkButton.OnClick(EventArgs e) +111
   System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +79
   System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +175
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565

我的代码是:

public void AddNewTempImage(Stream image, string extension, Guid PageId, Guid ImageId, 
    ImageTransformCollection toDoTransforms)
{
    //mapping steam to memory stream so it does support the seek

    MemoryStream targetStream = new MemoryStream(ReadStream(image, 1024));
    Image ImageToTransform=null;
    Image transformedImage = null;
    string storagePath = ImageTransformManager.Config.StorageServerPhysicalPath;
    Uri storageUrl = new Uri(ImageTransformManager.Config.StorageServerUrl);

    //string TempPath = Path.Combine(storagePath, GenerateFileName(extension));
    //SaveStream(TempPath, image);
    //File.WriteAllBytes(TempPath, ReadStream(image, 1024));

    if (!HttpContext.Current.User.Identity.IsAuthenticated)
        throw new Exception("Nonauthenticated users image submition is not supported");

        try
        {            
            foreach (ImageTransform transform in toDoTransforms)
            {
            ImageRepositoryTempImage newimage = new ImageRepositoryTempImage();
            newimage.ImageGuid = ImageId;
            newimage.PageGuid = PageId;
            newimage.CreatedBy = HttpContext.Current.User.Identity.Name;
            newimage.CreatedDate = DateTime.UtcNow;
            newimage.Format = transform.OutputType;
            newimage.Width = transform.Width;
            newimage.Height = transform.Height;
            newimage.Watermark = transform.UseWaterMark;
            string filename = GenerateFileName(transform.OutputType);
            string fullStoragePath = Path.Combine(storagePath, Path.Combine(transform.StorageFolder, filename));
            string fullStorageUrl = CombineUri(storageUrl, Path.Combine(transform.StorageFolder, filename));
            newimage.PhysicalStoragePath = fullStoragePath;
            newimage.StoragePath = fullStorageUrl;
            CheckOrAddImageTransform(transform);
            var ImgRepTransform = GetTransformation(transform);
            newimage.ImageRepositoryTransformation = ImgRepTransform;
            newimage.TransformId = ImgRepTransform.Id;

            Bitmap uploaded = new Bitmap(image);

            ImageToTransform = (Image)uploaded.Clone();
            uploaded.Dispose();
            transformedImage = transform.Transform(ImageToTransform);
            AddNewTempImage(newimage);
            //adding named watermark and transformation
            string wname = ImageTransformManager.Config.WaterMarkName;
            string wpath = ImageTransformManager.Config.WaterMarkPath;
            ChechOrAddWaterMark(wname, wpath);


            if (!(string.IsNullOrEmpty(wname) && string.IsNullOrEmpty(wpath)))
                newimage.ImageRepositoryWaterMark = GetWatermark(wname, wpath);

            transformedImage.Save(fullStoragePath, GetFormat(newimage.Format));
            }
        }
        catch (System.Exception ex)
        {
            ErrorHandling.LogErrorEvent("Add new temp image method", ex);
            throw ex;
        }
        finally
        {
            //File.Delete(TempPath);
            if (ImageToTransform!=null)
                ImageToTransform.Dispose();
            image.Dispose();
            targetStream.Dispose();
            if (transformedImage != null)
            transformedImage.Dispose();
        }

}

在我的本地机器上一切正常,但在服务器(2003)上仍然发生问题 - 我已经设置了文件夹权限和一切...


你能指出异常发生的那一行吗? - Igor Brejc
11个回答

27

我非常讨厌那个错误。 “Generic Error”可能是最无用的错误描述,它并不能告诉我们出了什么问题。

每次我遇到这个错误时,问题通常都与文件IO有关。

以下是我笔记中包含的修复列表- 不确定是否适用于您的问题,但对我来说通常都有奏效。

  • 检查文件路径
    • 确保父目录存在
    • 确保路径包括文件名和扩展名
    • 使用 server.MapPath() 来创建路径
  • 确保文件没有被写回其源。必要时关闭并重新打开流。

如果我从别处抄袭了这个列表,我很抱歉。它已经在我的笔记本上有一段时间了,我不记得它来自哪里了。


这确实是一个缺失的路径。 - sabbour
1
+1 恨之入骨!我也因为缺少路径而遇到了这个错误。 - Curtis
+1 确实,这也是我的文件路径问题。目录的路径是正确的,但我忘记在路径中加入文件名。 - Travis J
1
这对我有用:http://www.hanselman.com/blog/TheWeeklySourceCode50ALittleOnAGenericErrorOccurredInGDIAndTroubleGeneratingImagesOnWithASPNET.aspx(它在将图像写入响应流之前创建了一个中间流) - Cosmin
“通用错误可能是有史以来最无用的错误描述”,显然你从未遇到过由COM发出的“对象''的方法''失败”的错误。 - Martin Brown
@MartinBrown 是啊...我在职业生涯的幸福时刻发表了那个评论,那时我还没有接触过COM或Oracle。那些是如此快乐的时光。 - Kelly Robins

1
每个人(包括这个网站上的所有人)都认为这是由于权限错误引起的。我遇到了另一种情况:内存。我用完了内存,也开始收到这个错误。所以请将其视为另一个潜在的错误来源。
在我的特定情况下,我正在运行一个.NET应用程序,并针对多个线程运行(线程数量足够少,以至于GDI+进程范围锁定没有过多地阻碍我)。在主要任务完成后添加“GC.Collect()”似乎并没有对速度产生太大影响,但确实完全消除了内存不足错误。

0

不要使用直接路径

    System.Drawing.Image img = Base64ToImage(_ImagePath);
    img.Save(_attachmentPath, ImageFormat.Jpeg);

使用 Server.MapPath,它会在需要时创建目录。
    System.Drawing.Image img = Base64ToImage(_ImagePath);
    img.Save(Server.MapPath(_attachmentPath), ImageFormat.Jpeg);

0
你的本地机器是Vista还是Windows 7,而你的服务器是Windows Server 2003?我相信GDI+的实现不同,你在新的操作系统上不会看到这个错误。我现在刚遇到这个问题,这是我发现的其中一个要点。

0

请确保 IIS_WPGASPNET 在您的上传文件夹上拥有正确的权限

我之前也遇到了同样的问题,这个方法解决了它。

如果需要,在子文件夹中也要传播权限(我可能会忘记这一点.. :))


0

我同意权限是这里的问题。

可能是网络服务?


0
我刚刚遇到了同样的错误,谷歌帮我找到了答案: 加载/保存位图会导致文件被锁定。
解决方法是创建另一个位图,保存并释放它: Bitmap tmp = new Bitmap(bitmapToBeSaved); tmp.SaveToFile(fileName);

0

我在我的托管网站上遇到了一个类似的问题(相同的异常):原来是权限问题,ASP.NET帐户试图从其可用范围之外的目录读取图像文件。

我建议您仔细检查权限以及web.config中的<trust>元素,它应该设置为“中”或更高,具体取决于文件所在的位置。


0

这个问题困扰了我很长时间。是的,你可以检查权限,但你还应该正确地处理位图。

bitmap.Dispose();

0

尝试将应用程序池身份设置从ApplicationPoolIdentity更改为LocalSystem,以验证是否存在权限问题。

但是,不要长期使用此设置,因为它是安全风险;仅在诊断时使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接