Database Image Bank In MVC

The goal is to use a database to store images and use MVC to call those images, using custom routes.

The premises are,
  1. The URL must be something like this: “imagebank/sample-file” or “imagebank/32403404303“.
  2. The MVC Controller/Action will get the image by an ID “sample-file” or “32403404303” and find out on some cache and/or database to display the image. If it exists in cache, get from cache if not get from database. So in HTML, we can call the image like this.

    1. <img src="~/imagebank/sample-file" />    

  3. If you want to use another URL, for instance “foo/sample-file”, you can change the image bank route name in web.config.
  4. If you do not want to display the image and just download the file, use - “imagebank/sample-file/download“. 
So, let's get started! 
 
The image bank route configuration
 
App_Start\RouteConfig.cs
  1. public class RouteConfig  
  2.     {  
  3.         public static void RegisterRoutes(RouteCollection routes)  
  4.         {  
  5.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
  6.   
  7.             routes.MapRoute(  
  8.                 name: "ImageBank",  
  9.                 url: GetImageBankRoute() + "/{fileId}/{action}",  
  10.                 defaults: new { controller = "ImageBank", action = "Index" }  
  11.             );  
  12.   
  13.             routes.MapRoute(  
  14.                 name: "Default",  
  15.                 url: "{controller}/{action}/{id}",  
  16.                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }  
  17.             );  
  18.         }  
  19.   
  20.         private static string GetImageBankRoute()  
  21.         {  
  22.             var key = "imagebank:routeName";  
  23.             var config = ConfigurationManager.AppSettings.AllKeys.Contains(key) ? ConfigurationManager.AppSettings.Get(key) : "";  
  24.   
  25.             return config ?? "imagebank";  
  26.         }  
  27.     }  
The Image Bank Controller
 
Controllers\ImageBankController.cs  
  1. public class ImageBankController : Controller  
  2.     {  
  3.         public ImageBankController()  
  4.         {  
  5.             Cache = new Cache();  
  6.             Repository = new Repository();  
  7.         }  
  8.           
  9.         public ActionResult Index(string fileId, bool download = false)  
  10.         {  
  11.             var defaultImageNotFound = "pixel.gif";  
  12.             var defaultImageNotFoundPath = $"~/content/img/{defaultImageNotFound}";  
  13.             var defaultImageContentType = "image/gif";  
  14.   
  15.             var cacheKey = string.Format("imagebankfile_{0}", fileId);  
  16.             Models.ImageFile model = null;  
  17.   
  18.             if (Cache.NotExists(cacheKey))  
  19.             {  
  20.                 model = Repository.GetFile(fileId);  
  21.   
  22.                 if (model == null)  
  23.                 {  
  24.                     if (download)  
  25.                     {  
  26.                         return File(Server.MapPath(defaultImageNotFoundPath), defaultImageContentType, defaultImageNotFound);  
  27.                     }  
  28.   
  29.                     return File(Server.MapPath(defaultImageNotFoundPath), defaultImageContentType);  
  30.                 }  
  31.                   
  32.                 Cache.Insert(cacheKey, "Default", model);  
  33.             }  
  34.             else  
  35.             {  
  36.                 model = Cache.Get(cacheKey) as Models.ImageFile;  
  37.             }  
  38.   
  39.             if (download)  
  40.             {  
  41.                 return File(model.Body, model.ContentType, string.Concat(fileId, model.Extension));  
  42.             }  
  43.   
  44.             return File(model.Body, model.ContentType);  
  45.         }  
  46.   
  47.         public ActionResult Download(string fileId)  
  48.         {  
  49.             return Index(fileId, true);  
  50.         }  
  51.   
  52.         private Repository Repository { getset; }  
  53.   
  54.         private Cache Cache { getset; }  
  55.     }  
The above code has two actions - one for displaying the image and the other for downloading it. 

The database repository
 
Repository.cs
  1. public class Repository  
  2.     {  
  3.         public static Models.ImageFile GetFile(string fileId)  
  4.         {  
  5.             //Just an example, use you own data repository and/or database  
  6.             SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ImageBankDatabase"].ConnectionString);  
  7.   
  8.             try  
  9.             {  
  10.                 connection.Open();  
  11.                 var sql = @"SELECT *   
  12.                             FROM    dbo.ImageBankFile   
  13.                             WHERE   FileId = @fileId   
  14.                                     OR ISNULL(AliasId, FileId) = @fileId";  
  15.   
  16.                 var command = new SqlCommand(sql, connection);  
  17.                 command.Parameters.Add("@fileId", SqlDbType.VarChar).Value = fileId;  
  18.                 command.CommandType = CommandType.Text;  
  19.                 var ada = new SqlDataAdapter(command);  
  20.                 var dts = new DataSet();  
  21.                 ada.Fill(dts);  
  22.   
  23.                 var model = new Models.ImageFile();  
  24.                 model.Extension = dts.Tables[0].Rows[0]["Extension"as string;  
  25.                 model.ContentType = dts.Tables[0].Rows[0]["ContentType"as string;  
  26.                 model.Body = dts.Tables[0].Rows[0]["FileBody"as byte[];  
  27.   
  28.                 return model;  
  29.             }  
  30.             catch   
  31.             {  
  32.   
  33.             }  
  34.             finally  
  35.             {  
  36.                 if (connection != null)  
  37.                 {  
  38.                     connection.Close();  
  39.                     connection.Dispose();  
  40.                     connection = null;  
  41.                 }  
  42.             }  
  43.   
  44.             return null;  
  45.         }  
  46.     }  
The repository is very simple. This code is just for demonstration. You can implement your own code.  
 
The image bank model class
 
Models\ImageFile.cs
  1. public class ImageFile  
  2.     {  
  3.         public byte[] Body { getset; }  
  4.   
  5.         public string ContentType { getset; }  
  6.   
  7.         public string Extension { getset; }  
  8.     }   
Create table script
  1. USE [ImageBankDatabase]  
  2. GO  
  3.   
  4. /****** Object:  Table [dbo].[ImageBankFile]    Script Date: 11/16/2016 12:36:56 ******/  
  5. SET ANSI_NULLS ON  
  6. GO  
  7.   
  8. SET QUOTED_IDENTIFIER ON  
  9. GO  
  10.   
  11. SET ANSI_PADDING ON  
  12. GO  
  13.   
  14. CREATE TABLE [dbo].[ImageBankFile](  
  15.     [FileId] [nvarchar](50) NOT NULL,  
  16.     [AliasId] [nvarchar](100) NULL,  
  17.     [FileBody] [varbinary](maxNULL,  
  18.     [Extension] [nvarchar](5) NULL,  
  19.     [ContentType] [nvarchar](50) NULL,  
  20.  CONSTRAINT [PK_ImageBankFile] PRIMARY KEY CLUSTERED   
  21. (  
  22.     [FileId] ASC  
  23. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]  
  24. ON [PRIMARY]  
  25.   
  26. GO  
  27.   
  28. SET ANSI_PADDING OFF  
  29. GO   
The Cache provider class
 
Cache.cs 
  1. public class Cache  
  2.     {  
  3.         public Cache()  
  4.         {  
  5.             _config = ConfigurationManager.GetSection("system.web/caching/outputCacheSettings"as OutputCacheSettingsSection;  
  6.         }  
  7.           
  8.         private OutputCacheSettingsSection _config;  
  9.           
  10.         private OutputCacheProfile GetProfile(string profile)  
  11.         {  
  12.             return !string.IsNullOrEmpty(profile) ? _config.OutputCacheProfiles[profile] : new OutputCacheProfile("default");  
  13.         }  
  14.           
  15.         private object GetFromCache(string id)  
  16.         {  
  17.             if (string.IsNullOrEmpty(id)) throw new NullReferenceException("id is null");  
  18.             if (System.Web.HttpRuntime.Cache != null)  
  19.             {  
  20.                 lock (this)  
  21.                 {  
  22.                     return System.Web.HttpRuntime.Cache[id];  
  23.                 }  
  24.             }  
  25.   
  26.             return null;  
  27.         }  
  28.           
  29.         public Cache Insert(string id, string profile, object obj)  
  30.         {  
  31.             if (System.Web.HttpRuntime.Cache != null)  
  32.             {  
  33.                 if (string.IsNullOrEmpty(id))  
  34.                 {  
  35.                     throw new ArgumentNullException("id""id is null");  
  36.                 }  
  37.   
  38.                 if (string.IsNullOrEmpty(profile))  
  39.                 {  
  40.                     throw new ArgumentNullException("profile"string.Format("profile is null for id {0}", id));  
  41.                 }  
  42.   
  43.                 var objProfile = GetProfile(profile);  
  44.                 if (objProfile == null)  
  45.                 {  
  46.                     throw new NullReferenceException(string.Format("profile is null for id {0} and profile {1}", id, profile));  
  47.                 }  
  48.   
  49.                 lock (this)  
  50.                 {  
  51.                     System.Web.HttpRuntime.Cache.Insert(id, obj, null, DateTime.Now.AddSeconds(objProfile.Duration), TimeSpan.Zero);  
  52.                 }  
  53.             }  
  54.   
  55.             return this;  
  56.         }  
  57.           
  58.         public bool NotExists(string id)  
  59.         {  
  60.             return GetFromCache(id) == null;  
  61.         }  
  62.           
  63.         public Cache Remove(string id)  
  64.         {  
  65.             if (System.Web.HttpRuntime.Cache != null)  
  66.             {  
  67.                 lock (this)  
  68.                 {  
  69.                     System.Web.HttpRuntime.Cache.Remove(id);  
  70.                 }  
  71.             }  
  72.   
  73.             return this;  
  74.         }  
  75.           
  76.         public object Get(string id)  
  77.         {  
  78.             return GetFromCache(id);  
  79.         }  
  80.     }  
So that's it! I hope you enjoyed! Download full source code from here


Similar Articles