Here's my version of the code that works. What I've done is to remove the DB Open from the constructor and let each DB-related method open and close it's own connection:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
public class PhotoManager
{
private bool filter;
public PhotoManager()
{
filter = true;
if ( HttpContext.Current.User.IsInRole( "Friends" ) || HttpContext.Current.User.IsInRole( "Administrators" ) )
{
filter = false;
}
}
// Photo-Related Methods
public Stream GetPhoto( int photoid, PhotoSize size )
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetPhoto";
command.Parameters.Add( new SqlParameter( "@PhotoID", photoid ) );
command.Parameters.Add( new SqlParameter( "@Size", ( int )size ) );
command.Parameters.Add( new SqlParameter( "@IsPublic", filter ) );
object result = command.ExecuteScalar();
try
{
return new MemoryStream( ( byte[] )result );
}
catch ( ArgumentNullException e )
{
return null;
}
}
}
public Stream GetPhoto( PhotoSize size )
{
string path = HttpContext.Current.Server.MapPath( "~/Images/" );
switch ( size )
{
case PhotoSize.Small:
path += "placeholder-100.jpg";
break;
case PhotoSize.Medium:
path += "placeholder-200.jpg";
break;
case PhotoSize.Large:
path += "placeholder-600.jpg";
break;
default:
path += "placeholder-600.jpg";
break;
}
return new FileStream( path, FileMode.Open, FileAccess.Read, FileShare.Read );
}
public Stream GetFirstPhoto( int albumid, PhotoSize size )
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetFirstPhoto";
command.Parameters.Add( new SqlParameter( "@AlbumID", albumid ) );
command.Parameters.Add( new SqlParameter( "@Size", ( int )size ) );
command.Parameters.Add( new SqlParameter( "@IsPublic", filter ) );
object result = command.ExecuteScalar();
try
{
return new MemoryStream( ( byte[] )result );
}
catch ( ArgumentNullException e )
{
return null;
}
}
}
public List<Photo> GetPhotos( int AlbumID )
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetPhotos";
command.Parameters.Add( new SqlParameter( "@AlbumID", AlbumID ) );
command.Parameters.Add( new SqlParameter( "@IsPublic", filter ) );
SqlDataReader reader = command.ExecuteReader();
List<Photo> list = new List<Photo>();
while ( reader.Read() )
{
Photo temp = new Photo(
( int )reader[ "PhotoID" ],
( int )reader[ "AlbumID" ],
( string )reader[ "Caption" ] );
list.Add( temp );
}
return list;
}
}
public List<Photo> GetPhotos()
{
return GetPhotos( GetRandomAlbumID() );
}
public void AddPhoto( int AlbumID, string Caption, byte[] BytesOriginal )
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "AddPhoto";
command.Parameters.Add( new SqlParameter( "@AlbumID", AlbumID ) );
command.Parameters.Add( new SqlParameter( "@Caption", Caption ) );
command.Parameters.Add( new SqlParameter( "@BytesOriginal", BytesOriginal ) );
command.Parameters.Add( new SqlParameter( "@BytesFull", ResizeImageFile( BytesOriginal, 600 ) ) );
command.Parameters.Add( new SqlParameter( "@BytesPoster", ResizeImageFile( BytesOriginal, 198 ) ) );
command.Parameters.Add( new SqlParameter( "@BytesThumb", ResizeImageFile( BytesOriginal, 100 ) ) );
command.ExecuteNonQuery();
}
}
public void RemovePhoto( int original_PhotoID )
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "RemovePhoto";
command.Parameters.Add( new SqlParameter( "@PhotoID", original_PhotoID ) );
command.ExecuteNonQuery();
}
}
public void EditPhoto( string Caption, int original_PhotoID )
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "EditPhoto";
command.Parameters.Add( new SqlParameter( "@Caption", Caption ) );
command.Parameters.Add( new SqlParameter( "@original_PhotoID", original_PhotoID ) );
command.ExecuteNonQuery();
}
}
// Album-Related Methods
public List<Album> GetAlbums()
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetAlbums";
command.Parameters.Add( new SqlParameter( "@IsPublic", filter ) );
SqlDataReader reader = command.ExecuteReader();
List<Album> list = new List<Album>();
while ( reader.Read() )
{
Album temp = new Album(
( int )reader[ "AlbumID" ],
( int )reader[ "NumberOfPhotos" ],
( string )reader[ "Caption" ],
( bool )reader[ "IsPublic" ] );
list.Add( temp );
}
return list;
}
}
public void AddAlbum( string Caption, bool IsPublic )
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "AddAlbum";
command.Parameters.Add( new SqlParameter( "@Caption", Caption ) );
command.Parameters.Add( new SqlParameter( "@IsPublic", IsPublic ) );
command.ExecuteNonQuery();
}
}
public void RemoveAlbum( int original_AlbumID )
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "RemoveAlbum";
command.Parameters.Add( new SqlParameter( "@original_AlbumID", original_AlbumID ) );
command.ExecuteNonQuery();
}
}
public void EditAlbum( string Caption, bool IsPublic, int original_AlbumID )
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "EditAlbum";
command.Parameters.Add( new SqlParameter( "@Caption", Caption ) );
command.Parameters.Add( new SqlParameter( "@IsPublic", IsPublic ) );
command.Parameters.Add( new SqlParameter( "@original_AlbumID", original_AlbumID ) );
command.ExecuteNonQuery();
}
}
public int GetRandomAlbumID()
{
using ( SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings[ "Personal" ].ConnectionString ) )
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetNonEmptyAlbums";
SqlDataReader reader = command.ExecuteReader();
List<Album> list = new List<Album>();
while ( reader.Read() )
{
Album temp = new Album( ( int )reader[ "AlbumID" ], 0, "", false );
list.Add( temp );
}
reader.Close();
try
{
Random r = new Random();
return list[ r.Next( list.Count ) ].AlbumID;
}
catch ( ArgumentOutOfRangeException e )
{
return -1;
}
}
}
// Auxiliary Functions
private byte[] ResizeImageFile( byte[] imageFile, int targetSize )
{
System.Drawing.Image original = System.Drawing.Image.FromStream( new MemoryStream( imageFile ) );
int targetH, targetW;
if ( original.Height > original.Width )
{
targetH = targetSize;
targetW = ( int )( original.Width * ( ( float )targetSize / ( float )original.Height ) );
}
else
{
targetW = targetSize;
targetH = ( int )( original.Height * ( ( float )targetSize / ( float )original.Width ) );
}
System.Drawing.Image imgPhoto = System.Drawing.Image.FromStream( new MemoryStream( imageFile ) );
// Create a new blank canvas. The resized image will be drawn on this canvas.
Bitmap bmPhoto = new Bitmap( targetW, targetH, PixelFormat.Format24bppRgb );
bmPhoto.SetResolution( 72, 72 );
Graphics grPhoto = Graphics.FromImage( bmPhoto );
grPhoto.SmoothingMode = SmoothingMode.AntiAlias;
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.PixelOffsetMode = PixelOffsetMode.HighQuality;
grPhoto.DrawImage( imgPhoto, new Rectangle( 0, 0, targetW, targetH ), 0, 0, original.Width, original.Height, GraphicsUnit.Pixel );
// Save out to memory and then to a file. We dispose of all objects to make sure the files don't stay locked.
MemoryStream mm = new MemoryStream();
bmPhoto.Save( mm, System.Drawing.Imaging.ImageFormat.Jpeg );
original.Dispose();
imgPhoto.Dispose();
bmPhoto.Dispose();
grPhoto.Dispose();
return mm.GetBuffer();
}
public ICollection ListUploadDirectory()
{
DirectoryInfo d = new DirectoryInfo( System.Web.HttpContext.Current.Server.MapPath( "~/Upload" ) );
return d.GetFileSystemInfos( "*.jpg" );
}
}