The goal today is to create a small and quick ASP.NET MVC application that will allow us to upload and view images using MongoDB as the database. One of the methods for handling files with MongoDB is using Mongo’s GridFS specification. This method stores the file in chunks and stores those chunks in separate documents. The method we will use is more of a “classic” way to store images in databases. We will simply convert the bytes of the image to a string
and store it and do the reverse for viewing the image.
The Tools We’ll Need
- Visual Studio (I’m using VS 2013 express)
- The ASP.NET MVC framework (I’m using version 5)
- A MongoDB server instance (I’m running mine locally with the default settings)
- Already be little familiar with MVC and the mongoDB in general
Let’s Get Started
First, we’ll need to create a new web application proeject. Go to File on the menu and select “new project”.

On the next screen, select MVC with the default settings.

We now have a basic MVC web application template. Next, add a new controller by right-clicking the Controllers folder and selecting “add” and then “Controller”. Select empty MVC 5 controller. We should now have an empty gallery controller like so:

Get MongoDb Drivers From NuGet
To use the mongo database from this application, we will need to get the necessary drivers for C#. Open your Package Manager console and type the command:
Install-Package mongocsharpdriver
This will add the mongo c sharp drivers to your application from NuGet.
The Picture Model
Next, add a class to your models folder named MongoPictureModel.cs with the following:
using MongoDB.Bson;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MongoAndMVC.Models
{
public class MongoPictureModel
{
public ObjectId _id { get; set; }
public string FileName { get; set; }
public string PictureDataAsString { get; set; }
}
}
A couple of things to notice. We added a using
statement for the “MongoDB.Bson
” namespace
. We did this because we are using the type “ObjectId
” which is a type native to mongo. Now that we have our model, we can now edit our controller with the need functions.
GalleryController.cs
Update the gallery controller like so…
using MongoAndMVC.Models;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MongoAndMVCTutorial.Controllers
{
public class GalleryController : Controller
{
public ActionResult Index()
{
var theModel = GetThePictures();
return View(theModel);
}
public ActionResult AddPicture()
{
return View();
}
[HttpPost]
public ActionResult AddPicture(HttpPostedFileBase theFile)
{
if (theFile.ContentLength > 0)
{
string theFileName = Path.GetFileName(theFile.FileName);
byte[] thePictureAsBytes = new byte[theFile.ContentLength];
using (BinaryReader theReader = new BinaryReader(theFile.InputStream))
{
thePictureAsBytes = theReader.ReadBytes(theFile.ContentLength);
}
string thePictureDataAsString = Convert.ToBase64String(thePictureAsBytes);
MongoPictureModel thePicture = new MongoPictureModel()
{
FileName = theFileName,
PictureDataAsString = thePictureDataAsString
};
bool didItInsert = InsertPictureIntoDatabase(thePicture);
if (didItInsert)
ViewBag.Message = "The image was updated successfully";
else
ViewBag.Message = "A database error has occurred";
}
else
ViewBag.Message = "You must upload an image";
return View();
}
private bool InsertPictureIntoDatabase(MongoPictureModel thePicture)
{
var thePictureColleciton = GetPictureCollection();
var theResult = thePictureColleciton.Insert(thePicture);
return theResult.Ok;
}
private List<MongoPictureModel> GetThePictures()
{
var thePictureColleciton = GetPictureCollection();
var thePictureCursor = thePictureColleciton.FindAll();
thePictureCursor.SetFields(Fields.Include("_id", "FileName"));
return thePictureCursor.ToList() ?? new List<MongoPictureModel>();
}
public FileContentResult ShowPicture(string id)
{
var thePictureColleciton = GetPictureCollection();
var thePicture = thePictureColleciton.FindOneById(new ObjectId(id));
var thePictureDataAsBytes = Convert.FromBase64String(thePicture.PictureDataAsString);
return new FileContentResult(thePictureDataAsBytes, "image/jpeg");
}
private MongoCollection<MongoPictureModel> GetPictureCollection()
{
var theConnectionString = "mongodb://localhost";
var theDBClient = new MongoClient(theConnectionString);
var theServer = theDBClient.GetServer();
string databaseName = "PictureApplication";
var thePictureDB = theServer.GetDatabase(databaseName);
string theCollectionName = "pictures";
var thePictureColleciton = thePictureDB.GetCollection<MongoPictureModel>(theCollectionName);
return thePictureColleciton;
}
}
}
Let’s look at what we did here. The first thing that we did was add some new namespace
s from the Mongo driver library to help us access the mongo DB and give us access to some very useful classes for manipulating the mongo data.
MongoAndMVC.Models;
MongoDB.Bson;
MongoDB.Driver;
MongoDB.Driver.Builders;
We also added the System.IO namespace
for some of the byte manipulation that we’ll be doing.
GetPictureCollection Function
This function goes through the process of giving us a MongoCollection<T>
object that we can use for inserting and retrieving data. If the database or collection does not exist, the mongo database will create it on the fly.
ShowPicture Action
This action retrieves the picture data using the id passed in the URL. It will then take the data retrieved that was stored in string
format and convert back to an array of bytes. Since we are returning a FileContentResult
, this action will take the bytes and return them in the response in the designated “image/jpeg” mime type.
GetThePictures Function
This function returns a list of the MongoPictureModel
objects retrieved from the database. The thing we did different here is use the SetFields
function to reduce the fields we bring back. For the gallery page, we will only need the filename and ids of the pictures and not the data. We will get the image data from the individual calls to the ShowPicture
action. For the Gallery view, we only need to render the filename and id (which we use to make the URL for image tag’s src
attribute).
AddPicture Post Action
This action is the meat of what we are doing, but is very simple. First, we use the HttpPostedFileBase
object that is passed in from the file type input control in the view. We check to make sure that we have a file there, then we get the file’s name. We will use this for the FileName
property of the MongoPictureModel
object we will create. Next, we get the content stream of the file passed in and convert it to an array of bytes. We then convert that array of bytes into a base64
encoded string
. We use this data for the PictureDataAsString
property of our MongoPictureModel
. We then take our newly created model and pass it to our “InsertPictureIntoDatabase
” function.
Make your way back to the index view for the gallery controller and edit it to match this…
@model List<MongoAndMVC.Models.MongoPictureModel>
@{
ViewBag.Title = "Gallery";
}
<h2>Gallery</h2>
@Html.ActionLink("Add a new Picture", "AddPicture")
@foreach (var pictue in Model)
{
<div>
@pictue.FileName<br />
<img src="@string.Format("/Gallery/ShowPicture/{0}",pictue._id.ToString())" alt="@pictue.FileName" />
</div>
}
In the same directory, create a view named AddPicture.cshtml for the AddPicture
actions with this…
@{
ViewBag.Title = "Upload an image";
}
<h2>Upload a new image</h2>
@Html.ActionLink("View Gallery", "Index")
<div>
@if (ViewBag.Message != null && ViewBag.Message != "")
{
@ViewBag.Message
}
</div>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" id="theFile" name="theFile" />
<br />
<button type="submit">Upload Image</button>
</form>
Also edit the layout.cshtml file in the shared folder under views and add a link to the index action of the gallery controller in the app’s navigation.
Let’s Test It Out
Alright, fire up your web app and traverse to the gallery controller by going to “localhost/Gallery”. You should get something like this:

As you can see, we do not have any images yet, but we will soon rectify that. Click the “Add a new Picture” link and it should take you to the “Add a New Picture” page.

Simply click the input control and select a jpeg image to upload. If everything goes good, you should get the “The image was updated successfully
” message from the AddPicture
’s http post action.

Click “View Gallery” and go back to the gallery page. You should see your newly uploaded image loaded straight from a mongo database.

Nice!
Additional Notes
- You should carefully review the MongoDB documentation to come up with a file storage mechanism that’s more suited to your needs. The
GridFS
specification has its advantages (like no 16MB size limit) as well as some disadvantages vs storing files directly in the document vs just storing them on the file system. - This is just a tutorial, but if you are going to use some kind of method of image retrieval and display similar to this, you will be wise to come up with strategies to help alleviate the load on the DB such as paging and server side caching.
Download source files.
CodeProject