I'm not sure where this should go (I don't know whether it's a database problem, or a code problem), but I think it's a code problem, so I'm posting here.

I'm working with a database that is storing images (actually, it's a modified version of the AdventureWorks database from Microsoft), and I'm creating a form that will let you upload a file. I've got a business object based on the table that I'm using (Production.ProductPhoto) and I'm using two stored procedures to either get (Production.ProductPhoto_Get) or add (Production.ProductPhoto_Add) an entry from/to the table. The image is being stored as a varbinary field in the database, and a Byte() in my business object.

The problem I'm having is that when I'm adding a new entry and uploading a file, the length of the file uploaded is correct (so I assume everything is going smoothly), and it gets passed along to my ProductPhotoProvider DAL class where I create a DbCommand and add the parameters for my stored procedure. The information is all added to the database successfully, and I'm returned the identity of the new entry as expected -- however, when I try to read this image back, it seems that the length is 1. I've put in break points and stepped through everything, and I don't know what's going on.

I think that I know my ProductPhotoProvider class is at least reading things correctly -- I can display other images from the database (that came with the database, that is) just fine. Mine just all come back with a length of 1.

I'm just hoping someone knows what the hell I'm talking about; I have a lot of programming experience, but this is my first major venture into ASP.NET. I have no idea which parts of my code are relevant, so I'll just post my Add and Lookup functions for now?!

ProductPhotoProvider.Add:
vb Code:
  1. Public Shared Function Add(ByVal P As ProductPhoto) As Integer
  2.             Dim Command As DbCommand = GetCommand("Production.ProductPhoto_Add")
  3.             With Command.Parameters
  4.                 .Add(GetParameter("ThumbNailPhoto", DbType.Binary, P.ThumbnailPhoto))
  5.                 .Add(GetParameter("ThumbnailPhotoFileName", DbType.String, P.ThumbnailPhotoFilename))
  6.                 .Add(GetParameter("LargePhoto", DbType.Binary, P.LargePhoto))
  7.                 .Add(GetParameter("LargePhotoFileName", DbType.String, P.LargePhotoFilename))
  8.             End With
  9.             Return ExecuteScalar(Of Integer)(Command)
  10.         End Function

ProductPhotoProvider.Lookup:
vb Code:
  1. Public Shared Function Lookup(ByVal ProductPhotoID As Integer) As ProductPhoto
  2.             Dim Command As DbCommand = GetCommand("Production.ProductPhoto_Get")
  3.             With Command.Parameters
  4.                 .Add(GetParameter("ProductPhotoID", DbType.Int32, ProductPhotoID))
  5.             End With
  6.             Return Hydrator.FillObject(ExecuteReader(Command))
  7.         End Function

ProductPhotoProvider.Hydrator.FillObject:
vb Code:
  1. Public Shared Function FillObject(ByVal reader As INullableReader) As ProductPhoto
  2.                 CheckNullOrClosedReader(reader)
  3.                 Dim Result As ProductPhoto = Nothing
  4.                 Using reader
  5.                     If reader.Read Then
  6.                         Result = Hydrate(reader)
  7.                     End If
  8.                 End Using
  9.                 Return Result
  10.             End Function

ProductPhotoProvider.Hydrator.Hydrate:
vb Code:
  1. Private Shared Function Hydrate(ByVal reader As INullableReader) As ProductPhoto
  2.                 Dim ID As Integer = reader.GetInt32("ProductPhotoID")
  3.  
  4.                 'images must be read in as an array of Bytes; no GetByte!
  5.                 Dim ThumbnailIndex As Integer = reader.GetOrdinal("ThumbnailPhoto")
  6.                 Dim ThumbnailPhoto As Byte() = Nothing
  7.                 If Not reader.IsDBNull("ThumbnailPhoto") Then
  8.                     ThumbnailPhoto = CType(reader.GetValue(ThumbnailIndex), Byte())
  9.                 End If
  10.  
  11.                 Dim ThumbnailPhotoFilename As String = reader.GetNullableString("ThumbnailPhotoFilename")
  12.  
  13.                 'images must be read in as an array of Bytes; no GetByte!
  14.                 Dim LargePhotoIndex As Integer = reader.GetOrdinal("LargePhoto")
  15.                 Dim LargePhoto As Byte() = Nothing
  16.                 If Not reader.IsDBNull("LargePhoto") Then
  17.                     LargePhoto = CType(reader.GetValue(LargePhotoIndex), Byte())
  18.                 End If
  19.  
  20.                 Dim LargePhotoFilename As String = reader.GetNullableString("LargePhotoFilename")
  21.                 Dim ModifiedDate As Date = reader.GetDateTime("ModifiedDate")
  22.  
  23.                 Dim Result As ProductPhoto = New ProductPhoto(ID, ThumbnailPhoto, ThumbnailPhotoFilename, _
  24.                                                               LargePhoto, LargePhotoFilename, ModifiedDate)
  25.                 Return Result
  26.             End Function

My ProductPhotoProvider class is based off of an abstract class called AbstractDALProvider (which I can also provide if needed). I can provide the rest of my project, if needed, too.

Oh, and for good measure: I was told that when you used to store images in Microsoft Access, there was some sort of problem when retrieving the data and you'd have to strip the first 72 bytes of data from it, or something. I can only assume that this is not a problem here, because I have no problem displaying other photos that were not created by me.