2

(ASP.NET 3.5 Web Forms app, using WCF services (Fluent NHibernate) for data access)

I have an entity, let's call it Foo. Users can upload files as attachments to Foo. My upload and download functionality is "working" just fine...with one problem...when I open the files after downloading them I receive error messages informing me that the file is corrupt. The .txt, .docx and .xlsx files open anyway, after I click 'Ok' on the error msg, but all other file types fail to open. Google hasn't been much help, I'm hoping someone here might be able to point me in the right direction.

Upload Code:

// 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();
}

Download Code:

...
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();
}

Table:

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

---------------------Update 2013.05.07---------------------

After re-reading my post, I realize it may not be clear...I'm storing these files in the database.

When I retrieve the bytes from the database the byte[] always has a length of 8000, that doesn't seem right.

NHibernate Mapping:

<?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>
CDR12
  • 481
  • 6
  • 21
  • What browser are you testing this in? – rivarolle May 03 '13 at 20:59
  • Shot in the dark here - but try streaming everything EXCEPT the last byte back to the browser. For the life of me I can't remember the complete context, but this solved a similar issue for me before. – DanP May 03 '13 at 23:27
  • @rivarolle - IE9, I also tested in FireFox 20.0.1 this morning & got same result. Most, if not all, of my users will be using IE. – CDR12 May 07 '13 at 13:45
  • Possible duplicate of: http://stackoverflow.com/questions/4584170/binary-blob-truncated-to-8000-bytes-sql-server-2008-varbinarymax – DanP May 09 '13 at 17:19
  • Yes, [stackoverflow.com/questions/4584170](http://stackoverflow.com/questions/4584170/binary-blob-truncated-to-8000-bytes-sql-server-2008-varbinarymax) helped me resolve this issue. That post did not come up in my search prior to posting this question. – CDR12 May 13 '13 at 16:51

1 Answers1

0

After reading stackoverflow.com/questions/4584170, I changed my FooAttachment mapping class. Now I am able to download the attachments without issue.

Here is my new FooAttachmentMap class:

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");
    }
}

(Somehow stackoverflow.com/questions/4584170 did not appear in my search results prior to asking my question. I apologize for the duplicate).

Community
  • 1
  • 1
CDR12
  • 481
  • 6
  • 21