Month: April 2014

File Upload In MVC through GridFS of MongoDB

In this post we will be uploading a file in MVC through GridFS of MongoDB. Before going through the post it will be benefecial to have a knowledge of GridFS of MongoDB

Scenario :


 

We will be having a file uploader in our view where we will be uploading a file through GridFS MongoDB. For using MongoDB in MVC we have to set the MongoDB in our system and include the C# drivers of Mongo DB in our MVC project through NuGet package manager.

Razor Markup :


@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = “multipart/form-data” }))
{

<div class=”form-group”>
<div class=”col-lg-10 col-lg-offset-2″>
<input type=”file” id=”fileUpload” name=”file” />

</div>

</div>

<div class=”form-group”>
<div class=”col-lg-10 col-lg-offset-2″>

<input type=”submit” value=”upload” class=”btn btn-default” />
</div>
</div>
}

 

Here as you can see we have created a form where we have placed a file control with name as “file” and a submit button to post the file to the action(With same name as of the razor view) in Mvc controller .

Mongo Context Class :


Create a context Class (MongoContext ) to get the Mongo Interface references in all the actions of all the controllers. Place this file in the App_Start folder and Initialize it anywhere.

public MongoDatabase mgDatabase;
public MongoContext()
{

var client = new MongoClient(Settings.Default.MongoConnString);
var server = client.GetServer();
mgDatabase = server.GetDatabase(Settings.Default.MongoDBName);

}

Controller Action For Uploading Files :


 

In the controller create an instance of the Mongo Context class that we created earlier.

//Assembly references

using MongoDB.App_Start;
using MongoDB.Bson;
using MongoDB.Driver.Builders;
using MongoDB.Driver;
using MongoDB.Driver.GridFS;

 

 

//Creating Instance of MongoDB context

public readonly MongoContext context = new MongoContext();

 

[HttpPost]
public ActionResult AttachImage(HttpPostedFileBase file)
{
var options =new MongoGridFSCreateOptions{
//Id=imageID, If we want to link the file with a document
ContentType=file.ContentType
};
context.mgDatabase.GridFS.Upload(file.InputStream, file.FileName, options);
return RedirectToAction(“Index”);
}

In the above action method we have input param of type HttpPostedFileBase with name file which is basically the name of the file control in the razor view.

We can use the Upload method of the GridFS to save the posted file. In the above upload Api we have a field option which is very usefull to provide the configs like the content type (Mime type) and if we have to connect this file with a Bson document we can link them as done in options.

Graphical Representation :

To view the chunks and files of this uploaded file we can use the RoboMongo.

fs.files :

g2

 

fs.chunks :

g1

 

In the image above the left side object is basically the fs.files and the right side objects are the chunks (fs.chunks) of the file.

The file_id in the chunks is referring to the file to which the chunks belong. n refers to the sequential chain of the chunks referring to the same file.

File info like the file name , total file size , content type and associated chunks size can be seen the file object.

This is how we can upload a file through GridFS collection of MongoDB in MVC.

 

Advertisements

GridFS In MongoDB

There is a Lot said and asked about GridFS . In this post we will be going to have a Insight into GridFS feature of MongoDB.

What Exactly Is GridFS :


 

GridFS is an inbuilt feature of MongoDB through which it provides a Virtual File System for Storing Files , associating them with Mongo Documents(BSON Documents) and retrieving them when required.

 

Question : Why can’t we simply use the Bson documents to store the file?

Size : GridFS is basically for storing the files which are greater in size then 16MB.

Sync : When you want to keep your files and metadata automatically synced and deployed across a number of systems and facilities.

Platform Agnostic : Files can be stored alleviating many concerns of local file systems like maximum size of files in local directory.

Chunk Read Access : Suppose at a point you need just a part of your file rather then the complete file. As sometimes we need to see only a part of the video instead of the complete one. GridFS provides the capability of retrieving only that chunks of the file which is needed. So GridFS can be used to recall sections of files without reading the entire file into memory thus enhancing the performance.

FailOver And BackUp : As GridFS stores file in documents it has baked in support for replication and backup.

So after having a brief Idea of why we need GridFS let’s dive into the internals:

GridFS Collection :


 

GridFS stores files in two collections:

  • chunks stores the binary chunks.
  • files stores the file’s metadata.

GridFS places the collections in a common bucket by prefixing each with the bucket name. By default, GridFS uses two collections with names prefixed by fs bucket:

  • fs.files
  • fs.chunks

You can choose a different bucket name than fs, and create multiple buckets in a single database.

Each document in the chunks collection represents a distinct chunk of a file as represented in the GridFS store. Each chunk is identified by its unique ObjectId stored in its _id field. Default Size of a chunk is 256KB which can be modified.

                                    Image

Elements inside these two entities will give you a better idea:

Image

 

In the chunks schema :

_id is the basic object id that is assigned to every chunk. file_id is the id of the file stored in fs.files which contain the metadata of the chunk. n is used for indexing and data contain the actual binary stream of data.

In the files schema :

We have different options which can be configured like chunk size and content type(For storing Mime type).

Metadata will contain the file info , MD5 will contain a hash which is useful to confirm that the chunks are stored correctly.

So this is how GridFS provides a storng , efficient and configurable way to handle big files in MongoDB.


 

Drag & Drop File Upload With Progress Bar

Here we will be creating a Drag and Drop uploader in Jquery that will  be showing a progress bar for a real time idea of bytes stream transfer at server end.

DROPZONE:


Dropzone is the name given to the content area where we can drop files in the browser. The size of the dropzone depends on the user needs , In this demo we will be making the complete page as a dropzone. For achieving this we have to place a div inside the form tag inside which all other controls of the page will reside:

Markup:

<div id=”dropzone”>

<progress id=”progressBar”  max=”100″ value=”0″>0% complete</progress>

<div id=”divDroppedDocuments”></div>

<input type=”button” id=”btnUpload” value=”Upload”/>

</div>

This Dropzone will be used for the dropping of the files which are going to be uploaded.

CONCEPT:


When we select a file from anywhere on the computer and drags it to the browser ,we have to notify the user what he can do with these files. Like for example we can grey out the background and show a text like ” DROP FILES ” . If the user Drops the files we have to stop the default behavior of showing the files in the browser and collect the files to upload them. If the user doesn’t drops the files then we have to remove the grayed out area or any other style that we placed inside the dragover . For handling these behaviors in jquery we will be using below mentioned three events:

 “dragover”, “dragleave”, “drop”

DRAGOVER:


//Dragover event for the dropzone

$(“#dropzone”).on(“dragover”, function (event) {

//Below code stops the default behaviour

event.preventDefault();

event.stopPropagation();

$(this).addClass(‘dragging’); });

” dragging ” is a class where you can put the background color or other informative animations.

DRAGLEAVE:


//DragLeave event for the dropzone

$(“#dropzone”).on(“dragleave”, function (event) {

event.preventDefault();

event.stopPropagation();

$(this).removeClass(‘dragging’); });

DROP:


In the drop event we will grab the files and store them in global variables and show the end user a template of dropped files having info like name and size of the dropped files.

//Drop event for the dropzone

$(“#dropzone”).on(“drop”, function (e) {

e.preventDefault();

e.stopPropagation();

$(this).removeClass(‘dragging’);

filesToUpload = [];//Global Variable

formData = new FormData();//Global Variable

for (var i = 0; i < e.originalEvent.dataTransfer.files.length; i++)

{

var objDroppedFiles = {};

objDroppedFiles[‘name’] = e.originalEvent.dataTransfer.files[i].name;

objDroppedFiles[‘size’] = e.originalEvent.dataTransfer.files[i].size;

objDroppedFiles[‘extension’] = e.originalEvent.dataTransfer.files[i].type.split(‘/’)[1]; filesToUpload.push(objDroppedFiles);

}

//Genrating templates for showing name and size of the dropped files.

var tableStart = ‘<table class=”tblUpload”>’; var tableEnd = ‘</table>’;

for (var i = 0; i < filesToUpload.length; i++)

{

var tr = “<tr style=’height:50px’><td><label class=’lblUploads’ >Name:</label><input type=’text’ value='” + filesToUpload[i].name + “‘  /></td><td><label class=’lblUploads’>Size: </label></td><td> <label>”+filesToUpload[i].size +”</label></td></tr>” tableStart = tableStart + tr;

}

$(‘#divDroppedDocuments’).html(tableStart + tableEnd);

var files = e.originalEvent.dataTransfer.files;

for (var i = 0; i < files.length; i++)

{

formData.append(‘file’, files[i]);

} });

UPLOADING THE FILES ON BUTTON CLICK:


//Event for Uploading the files

$(‘#btnUpload’).click(function () {

// now post a new XHR request

var xhr = new XMLHttpRequest();

xhr.open(‘POST’, ‘Upload.aspx’, true);//true is for async call

//Function for tracking the progress

function progressFunction(evt) {

var progressBar = document.getElementById(“progressBar”);

if (evt.lengthComputable) { progressBar.max = evt.total; progressBar.value = evt.loaded; }

}

xhr.upload.addEventListener(“progress”, progressFunction, false);

xhr.onload = function () { if (xhr.status === 200) { console.log(‘all done: ‘ + xhr.status); } }; xhr.send(formData); });

This is a plain simple way of uploading a file through Drag and Drop without using any plugin. Hope it helps . Feel free for any assistance related to code blocks

Kendo Treeview Inside Dropdown

Kendo UI provides a whole vast set of Out Of Box Controls .

We will be covering one controls which is highly sought but yet not present in kendo Library.

Kendo Node Dropdown ( Fusion of kendo treeview and kendo dropdown controls)


Kendo Node Dropdown


HTML Markup :

We will create an Un-ordered list of the data which we want to show as treeview inside the dropdown.

For the demo I will be creating a UL with static data. But the Un-ordered list can also be created with dynamic data like looping through a model in razor view of MVC.

Untitled

An input element for the Kendo Dropdown

  Untitled1

JQUERY CODE :

Untitled3

For finding the selected node we have to find out the selected text of the dropdown as below:

Untitled2

This is how a fusion of Kendo Tree view and Kendo dropdown can be created . Hope someday the parent nodes will also go the same way .

Will be coming up with few other Out of box combinations .

Kendo UI Tip 3 : Destroying Kendo Grid

Sometimes we need to create a div to kendo grid again and again.

Properly destroying a kendo grid is very important to cease any forthcoming UI as well as functionality issue due to any type of remains of previous grid.

Before creating the grid again just destroy the previously created grid and clear it’s wrapper as shown below:

var grid = $(“#divGrid”).data(“kendoGrid”);

if (grid) {

//destroy the previous Grid instance
grid.destroy();

//clean up the html
grid.wrapper.html(“”);
}

 

Hope this helps 🙂 .

Kendo UI Tip 2 : Conditional Inline Editing In Kendo Grid

Sometimes while using Inline Editing in Kendo Grid we require to perform a check and based on that we have to perform the editing.

Suppose there is a column Area in the Model and based on it’s value you want to modify the Size column.

Initially the size column will be editable but inside the Edit function of Kendo Grid , based on a condition you can close the cell and prevent the editing.

Untitled

This is how you can handle the editing of kendo grid cells based on a condition.

Hope this helps 🙂

Kendo UI Tip 1 : Customizing Kendo SelectList Icons

Some times the theme of the application requires us to use some custom icons on the kendo controls (Dropdowns or Comboboxes) . Here is how to apply them ==>>

You can easily do it with CSS :

.k-icon.k-i-arrow-s {
background-image: url(YourImageURL);
background-position: 0 0;
background-size: 16px 16px;
}

You can set the size of your choice and reference the image that you want to show .

Hope this helps 🙂