The goal is to use a database to store images and use MVC to call those images, using custom routes.
The premises are,
- The URL must be something like this: “imagebank/sample-file” or “imagebank/32403404303“.
- 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.
- <img src="~/imagebank/sample-file" />
- If you want to use another URL, for instance “foo/sample-file”, you can change the image bank route name in web.config.
- 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
- public class RouteConfig
- {
- public static void RegisterRoutes(RouteCollection routes)
- {
- routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
- routes.MapRoute(
- name: "ImageBank",
- url: GetImageBankRoute() + "/{fileId}/{action}",
- defaults: new { controller = "ImageBank", action = "Index" }
- );
- routes.MapRoute(
- name: "Default",
- url: "{controller}/{action}/{id}",
- defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
- );
- }
- private static string GetImageBankRoute()
- {
- var key = "imagebank:routeName";
- var config = ConfigurationManager.AppSettings.AllKeys.Contains(key) ? ConfigurationManager.AppSettings.Get(key) : "";
- return config ?? "imagebank";
- }
- }
Controllers\ImageBankController.cs
- public class ImageBankController : Controller
- {
- public ImageBankController()
- {
- Cache = new Cache();
- Repository = new Repository();
- }
- public ActionResult Index(string fileId, bool download = false)
- {
- var defaultImageNotFound = "pixel.gif";
- var defaultImageNotFoundPath = $"~/content/img/{defaultImageNotFound}";
- var defaultImageContentType = "image/gif";
- var cacheKey = string.Format("imagebankfile_{0}", fileId);
- Models.ImageFile model = null;
- if (Cache.NotExists(cacheKey))
- {
- model = Repository.GetFile(fileId);
- if (model == null)
- {
- if (download)
- {
- return File(Server.MapPath(defaultImageNotFoundPath), defaultImageContentType, defaultImageNotFound);
- }
- return File(Server.MapPath(defaultImageNotFoundPath), defaultImageContentType);
- }
- Cache.Insert(cacheKey, "Default", model);
- }
- else
- {
- model = Cache.Get(cacheKey) as Models.ImageFile;
- }
- if (download)
- {
- return File(model.Body, model.ContentType, string.Concat(fileId, model.Extension));
- }
- return File(model.Body, model.ContentType);
- }
- public ActionResult Download(string fileId)
- {
- return Index(fileId, true);
- }
- private Repository Repository { get; set; }
- private Cache Cache { get; set; }
- }
The database repository
Repository.cs
- public class Repository
- {
- public static Models.ImageFile GetFile(string fileId)
- {
- //Just an example, use you own data repository and/or database
- SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ImageBankDatabase"].ConnectionString);
- try
- {
- connection.Open();
- var sql = @"SELECT *
- FROM dbo.ImageBankFile
- WHERE FileId = @fileId
- OR ISNULL(AliasId, FileId) = @fileId";
- var command = new SqlCommand(sql, connection);
- command.Parameters.Add("@fileId", SqlDbType.VarChar).Value = fileId;
- command.CommandType = CommandType.Text;
- var ada = new SqlDataAdapter(command);
- var dts = new DataSet();
- ada.Fill(dts);
- var model = new Models.ImageFile();
- model.Extension = dts.Tables[0].Rows[0]["Extension"] as string;
- model.ContentType = dts.Tables[0].Rows[0]["ContentType"] as string;
- model.Body = dts.Tables[0].Rows[0]["FileBody"] as byte[];
- return model;
- }
- catch
- {
- }
- finally
- {
- if (connection != null)
- {
- connection.Close();
- connection.Dispose();
- connection = null;
- }
- }
- return null;
- }
- }

Join the conversation! Your thoughts help the community grow.