【问题标题】:Files stored in DB are "corrupt" when retrieved检索时存储在 DB 中的文件“损坏”
【发布时间】:2013-04-28 06:14:27
【问题描述】:

(ASP.NET 3.5 Web 窗体应用,使用 WCF 服务 (Fluent NHibernate) 进行数据访问)

我有一个实体,我们称之为 Foo。用户可以将文件作为附件上传到 Foo。 我的上传和下载功能“工作”得很好......有一个问题......当我下载文件后打开文件时,我收到错误消息,通知我文件已损坏。 .txt、.docx 和 .xlsx 文件在我单击错误消息上的“确定”后仍然打开,但所有其他文件类型都无法打开。 谷歌并没有提供太多帮助,我希望这里的人能够为我指出正确的方向。

上传代码:

// Attachment is a FileUpload control
if (Attachment.HasFile)
{
    HttpPostedFile file = Attachment.PostedFile;
    FooContract foo = FooService.LookupFoo(FooId.Value, CurrentUser.Id);
    int contentLength = file.ContentLength;

    // Allocate a buffer for reading the file
    byte[] fileData = new byte[contentLength];
    // Read uploaded file from the Stream
    file.InputStream.Read(fileData, 0, contentLength);

    FooAttachmentContract attachment = new FooAttachmentContract();
    attachment.FileSize = contentLength.ToString();
    attachment.FileName = Path.GetFileName(Attachment.FileName);
    attachment.ContentType = file.ContentType;
    attachment.FooId = foo.Id;
    _attachments.Add(FooService.AddFooAttachment(attachment, fileData, CurrentUser.Id));
    // Clear cache
    Session["Attachments"] = null;
    // Rebind grid
    BindAttachmentGrid();
}

下载代码:

...
if([user has permission])
{
    DownloadFileResponse response = FooService.RetrieveAttachment(attachmentId, CurrentUser.Id);
    DownloadAttachment(response.Attachment.ContentType, response.Attachment.FileName, response.FileBytes);
}
else
    AccessDenied();
...


protected void DownloadAttachment(string mimeType, string fileName, byte[] file)
{
    Response.Clear();
    Response.ContentType = mimeType;
    Response.AddHeader("content-disposition", string.Format("attachment;filename=\"{0}\"", fileName));
    Response.BinaryWrite(file);
    Response.Flush();
    Response.End();
}

表格:

Id          int (PK)
FooId       int (FK)
FileName    varchar(100)
FileBytes   varbinary(MAX)
ContentType varchar(100)
FileSize    bigint
IsDeleted   bit

----------更新2013.05.07---------------------

重新阅读我的帖子后,我意识到可能不清楚...我将这些文件存储在数据库中。

当我从数据库中检索字节时,byte[] 的长度总是 8000,这似乎不对。

NHibernate 映射:

<?xml version="1.0"?>
-<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> 
    -<class xmlns="urn:nhibernate-mapping-2.2" table="`FooAttachment`" name="MyWebApp.Domain.Model.FooAttachment, MyWebApp.Domain, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null"> 
        -<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <column name="Id"/> <generator class="identity"/> </id> 
        -<property name="ContentType" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <column name="ContentType"/> </property> 
        -<property name="CreatedBy" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <column name="CreatedBy"/> </property> 
        -<property name="DateCreated" type="System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <column name="DateCreated"/> </property> 
        -<property name="FileBytes" type="System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <column name="FileBytes"/> </property> 
        -<property name="FileName" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <column name="FileName"/> </property> 
        -<property name="FileSize" type="System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <column name="FileSize"/> </property> 
        -<property name="IsDeleted" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <column name="IsDeleted"/> </property> 
        -<property name="LastModified" type="System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <column name="LastModified"/> </property> 
        -<property name="LastModifiedBy" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <column name="LastModifiedBy"/> </property> 
        -<many-to-one name="Foo" class="MyWebApp.Domain.Model.Foo, MyWebApp.Domain, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null"> <column name="FooId"/> </many-to-one> 
    </class> 
</hibernate-mapping>

【问题讨论】:

  • 你在什么浏览器中测试这个?
  • 这里在黑暗中拍摄 - 但尝试将除了最后一个字节之外的所有内容流式传输回浏览器。在我的一生中,我不记得完整的上下文,但这之前为我解决了一个类似的问题。
  • @rivarolle - IE9,我今天早上也在 FireFox 20.0.1 中进行了测试,得到了相同的结果。大多数(如果不是全部)我的用户将使用 IE。
  • 是的,stackoverflow.com/questions/4584170 帮助我解决了这个问题。在发布此问题之前,我的搜索中没有出现该帖子。

标签: asp.net sql webforms


【解决方案1】:

阅读stackoverflow.com/questions/4584170 后,我更改了我的FooAttachment 映射类。现在我可以毫无问题地下载附件了。

这是我的新 FooAttachmentMap 类:

public class FooAttachmentMap : ClassMap<FooAttachment>
{
    public FooAttachmentMap()
    {
        Id(x => x.Id);
        Map(x => x.ContentType);
        Map(x => x.CreatedBy);
        Map(x => x.DateCreated);
        Map(x => x.FileBytes)
            .Length(int.MaxValue);
        Map(x => x.FileName);
        Map(x => x.FileSize);
        Map(x => x.IsDeleted);
        Map(x => x.LastModified);
        Map(x => x.LastModifiedBy);
        References(x => x.Foo)
            .Column("FooId");
    }
}

(不知何故,stackoverflow.com/questions/4584170 在提出我的问题之前没有出现在我的搜索结果中。我为重复道歉)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    相关资源
    最近更新 更多