Image cropping using Jcrop in ASP.NET MVC Application

What is Image cropping?

  • Image cropping refer to removal of some part of image
  • Uses to improve framing and size
  • Applied in photograph to resize image

Application overview
In this project, I will show image cropping of an employee phot when employee information saved and modified. Full crud operation applied in the application with image cropping.
Let’s have a look on the implementation of the project.

Tools and Technology used

I used following tools and technology to develop the project –

  1. Visual Studio 2015
  2. Visual C#
  3. ASP.NET MVC
  4. Entity Framework 5
  5. Razor view engine
  6. JCrop

Step 1: Create a ASP.net MVC Project
File -> New project and select the project template Visual C# -> ASP.NET Web Application (.NET Framework) -> Console application (.NET Core).

0108_01

Select MVC as a Template as ASP.NET Template and click OK

0108_02

Step 2: Change or Add Connection String
Change or Add connection string in Web.config as follows

  
    
  
  

Step 3: Install JCrop Nuget Package
Go to Tools -> NuGet Package Manager -> Manages NuGet Package Manager for the solution -> Search Jcrop and install jquery.jcrop.js

0108_02_B

Step 4: Create model class

Create model class “Employee” as follows.

Employee Class

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace JCropMVC.Models
{
    public class Employee
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Display(Name = "Full Name")]
        [Required(ErrorMessage = "Name cannot be empty")]
        public string Name { get; set; }

        [Display(Name = "Father Name")]
        public string FatherName { get; set; }

        [Display(Name = "Designation")]
        public string Designation { get; set; }

        [Display(Name = "Mobile No")]
        public string Mobile { get; set; }

        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email")]
        public string Email { get; set; }

        [Display(Name = "Image URL")]
        public string PhotoURL { get; set; }
    }
}

Step 5: Modify Context class
Modify ApplicationDbContext in IdentityModel Class

    public class ApplicationDbContext : IdentityDbContext
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }

        public DbSet Employees { get; set; }
    }

Step 6: Create Controller and Views
Create Employees Controller and Views
Click Right button on Controller Folder->Add Controller. Now choose scaffolding template as MVC Controllers with views using Entity Framework and then Click Add.

0108_03

Now select Model class as Employee and Data Context Class as ApplicationDbContext as follows. Then click OK.

0108_04

Step 7: Modify the controller
Modify EmployeesController as follows. Here method ProcessImage(string croppedImage) is used to process and save image. An extra parameter added for Create and Edit action.

using System;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using JCropMVC.Models;
using System.IO;

namespace JCropMVC.Controllers
{
    public class EmployeesController : Controller
    {
        private ApplicationDbContext db = new ApplicationDbContext();

        // GET: Employees
        public ActionResult Index()
        {
            return View(db.Employees.ToList());
        }

        // GET: Employees/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Employee employee = db.Employees.Find(id);
            if (employee == null)
            {
                return HttpNotFound();
            }
            return View(employee);
        }

        // GET: Employees/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Employees/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Name,FatherName,Designation,Mobile,Email,PhotoURL")] Employee employee, string avatarCropped)
        {
            string filePath = ProcessImage(avatarCropped);
            employee.PhotoURL = filePath;

            if (ModelState.IsValid)
            {
                db.Employees.Add(employee);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(employee);
        }

        /// 
        /// Process image and save in predefined path
        /// 
        /// 
        /// 
        private string ProcessImage(string croppedImage)
        {
            string filePath = String.Empty;
            try
            {
                string base64 = croppedImage;
                byte[] bytes = Convert.FromBase64String(base64.Split(',')[1]);
                filePath = "/Images/Photo/Emp-" + Guid.NewGuid() + ".png";
                using (FileStream stream = new FileStream(Server.MapPath(filePath), FileMode.Create))
                {
                    stream.Write(bytes, 0, bytes.Length);
                    stream.Flush();
                }
            }
            catch (Exception ex)
            {
                string st = ex.Message;
            }

            return filePath;
        }

        // GET: Employees/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Employee employee = db.Employees.Find(id);
            if (employee == null)
            {
                return HttpNotFound();
            }
            return View(employee);
        }

        // POST: Employees/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Name,FatherName,Designation,Mobile,Email,PhotoURL")] Employee employee, string avatarCropped)
        {
            string filePath = ProcessImage(avatarCropped);
            employee.PhotoURL = filePath;

            if (ModelState.IsValid)
            {
                db.Entry(employee).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(employee);
        }

        //[Authorize(Users ="sumon")]
        // GET: Employees/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Employee employee = db.Employees.Find(id);
            if (employee == null)
            {
                return HttpNotFound();
            }
            return View(employee);
        }

        // POST: Employees/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Employee employee = db.Employees.Find(id);
            db.Employees.Remove(employee);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

Step 8: Modify the views for Employee

Create.cshtml

@model JCropMVC.Models.Employee

@{
    ViewBag.Title = "Create";
}



@using (Html.BeginForm("Create", "Employees", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()

    
@Html.ValidationSummary(true)
@Html.LabelFor(model => model.Name, new { @class = "" }) @Html.TextBoxFor(model => model.Name, new { @class = "form-control", placeholder = "Enter employee full name...", type = "text" }) @Html.ValidationMessageFor(model => model.Name)
@Html.LabelFor(model => model.FatherName, new { @class = "" }) @Html.TextBoxFor(model => model.FatherName, new { @class = "form-control", placeholder = "Enter father name...", type = "text" }) @Html.ValidationMessageFor(model => model.FatherName)
@Html.LabelFor(model => model.Designation, new { @class = "" }) @Html.TextBoxFor(model => model.Designation, new { @class = "form-control", placeholder = "Enter designation name...", type = "text" }) @Html.ValidationMessageFor(model => model.Designation)
@Html.LabelFor(model => model.Mobile, new { @class = "" }) @Html.TextBoxFor(model => model.Mobile, new { @class = "form-control", placeholder = "Enter mobile number...", type = "text" }) @Html.ValidationMessageFor(model => model.Mobile)
@Html.LabelFor(model => model.Email, new { @class = "" }) @Html.TextBoxFor(model => model.Email, new { @class = "form-control", placeholder = "Enter email address...", type = "text" }) @Html.ValidationMessageFor(model => model.Email)
@Html.LabelFor(model => model.PhotoURL, new { @class = "" })
Width:   Height: Crop Image
Employee Image

}
@Html.ActionLink("Back to List", "Index")
@section Scripts { @Scripts.Render("~/bundles/jqueryval") }

Edit.cshtml

@model JCropMVC.Models.Employee

@{
    ViewBag.Title = "Edit";
}

Edit

@using (Html.BeginForm()) { @Html.AntiForgeryToken() @*
*@

Employee


@Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.HiddenFor(model => model.Id)
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "" }) @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.FatherName, htmlAttributes: new { @class = "" }) @Html.EditorFor(model => model.FatherName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.FatherName, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.Designation, htmlAttributes: new { @class = "" }) @Html.EditorFor(model => model.Designation, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Designation, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.Mobile, htmlAttributes: new { @class = "" }) @Html.EditorFor(model => model.Mobile, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Mobile, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "" }) @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
@*
@Html.LabelFor(model => model.PhotoURL, htmlAttributes: new { @class = "" })
@Html.EditorFor(model => model.PhotoURL, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.PhotoURL, "", new { @class = "text-danger" })
*@
@Html.LabelFor(model => model.PhotoURL, new { @class = "" })
Width:   Height: Crop Image
Employee Image

@*
*@ }
@Html.ActionLink("Back to List", "Index")
@section Scripts { @Scripts.Render("~/bundles/jqueryval") }

Index.cshtml

@model IEnumerable

@{
    ViewBag.Title = "Index";
}

Index

@Html.ActionLink("Create New", "Create")

@foreach (var item in Model) { }
@Html.DisplayNameFor(model => model.Name) @Html.DisplayNameFor(model => model.FatherName) @Html.DisplayNameFor(model => model.Designation) @Html.DisplayNameFor(model => model.Mobile) @Html.DisplayNameFor(model => model.Email) @Html.DisplayNameFor(model => model.PhotoURL)
@Html.DisplayFor(modelItem => item.Name) @Html.DisplayFor(modelItem => item.FatherName) @Html.DisplayFor(modelItem => item.Designation) @Html.DisplayFor(modelItem => item.Mobile) @Html.DisplayFor(modelItem => item.Email) @**@ @*@Html.DisplayFor(modelItem => item.PhotoURL)*@ @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | @Html.ActionLink("Details", "Details", new { id=item.Id }) | @Html.ActionLink("Delete", "Delete", new { id=item.Id })

Delete.cshtml

@model JCropMVC.Models.Employee

@{
    ViewBag.Title = "Delete";
}

Delete

Are you sure you want to delete this?

Employee


@Html.DisplayNameFor(model => model.Name)
@Html.DisplayFor(model => model.Name)
@Html.DisplayNameFor(model => model.FatherName)
@Html.DisplayFor(model => model.FatherName)
@Html.DisplayNameFor(model => model.Designation)
@Html.DisplayFor(model => model.Designation)
@Html.DisplayNameFor(model => model.Mobile)
@Html.DisplayFor(model => model.Mobile)
@Html.DisplayNameFor(model => model.Email)
@Html.DisplayFor(model => model.Email)
@Html.DisplayNameFor(model => model.PhotoURL)
@Html.DisplayFor(model => model.PhotoURL)
@using (Html.BeginForm()) { @Html.AntiForgeryToken()
| @Html.ActionLink("Back to List", "Index")
}

Step 9: Add image folders
Add Image folders and sub folders (Deafult and Photo) as follows. Add blank photo in the Default folder to show blank photo for the employee.

0108_05

Step 10: Add Employee link
Add Employee link in the nav bar of _Layout page as follows.

                

Step 11: Run the application
Now run the application. Click Employee link in the nav bar. You can View, add, modify and delete employee information. If you go to the create or edit page, you have an option to upload photo and have option to crop the image and then save the image with employee information. Yes! You are done. Let’s cheers!

0108_06

Retrieving a collection of objects with page methods and AngularJS in ASP.NET Web form

Page Methods are asp.net web form feature. It is an easy way to communicate with the server. You can communicate with server using Page Methods and can do anything you like but mind it is not restful form of communication. In this solution I used visual studio 2012 and bootstrap. So let’s start to retrieve a collection of objects with Page Methods and AngularJS in ASP.NET web forms.

Step 1: Create a ASP.NET Web Forms Application

Open visual studio, Got to File->New->Project
Select Template -> Visual C# -> Web -> ASP.NET Empty web application, set location and click OK

Step 2: Install required packages

Run the following command in Package Manager Console (Tools->Library Package Manager->Package Manager Console) to install required package. Make sure your internet connection is enabled.

PM> Install-Package AngularJS.Core
PM> Install-Package AngularJS.Resource
PM> Install-Package bootstrap

Step 3: Design Master Page

Add required references for bootstrap and AngularJS and design master page using bootstrap as follows.
You can use theme. For details visit the article “ Easy way to design web layout by bootstrap theme


<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebMathodAngular.Site" %>





    

    
    

    
    


    
    

Here you must see that I used the reference of app.js, data.js. studentCtrl.js which are not defined yet. Soon, I will create those files. Another thing that you must set EnablePageMethod=”True”

Step 4: Create Application module, data and angular controller
Create app.js, data.js and studentCtrl.js in scripts -> app folder. Content are given below.

app.js

var app = angular.module('app', ['ngResource']);

data.js

app.value('pageMethods', PageMethods);

app.factory('student', function (pageMethods, $rootScope) {
    var result = [];
    pageMethods.GetStudent(function (data) {
        data.forEach(function (item) {
            result.push({ id: item.Id, name: item.Name, semester: item.Semester, credits: item.Credits});
        });
        $rootScope.$apply();
    });
    return result;
})

studentCtrl.js

app.controller('studentsCtrl', function ($scope, student) {
    $scope.student = student;
});

Here, App.js for just declaring application module, data.js for retrieving data using Page Methods and studentCtrl.js is the main angular controller. You must see, in data.js I have declare pageMethods and call a Page Method name “GetStudent”. This is not yet defines. I will create this method in next Step.

Step 4: Create a Page for View

Create a page name Default.aspx, just right click on the application -> Add -> New item -> Web form using master page. Select Master page and type page name as Default.aspx. Now modify the page as follows.

Default.aspx.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebMathodAngular
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        [WebMethod]
        public static List GetStudent()
        {
            List lstStudents = new List()
                {
				new Student { Id= 1, Name= "Mahedee Hasan", Semester="5th", Credits= 15},
				new Student { Id= 2, Name= "Robiul Alam", Semester="4th", Credits= 20},
				new Student { Id= 3, Name= "Amit Karmaker", Semester="7th", Credits= 12 },
				new Student { Id= 4, Name= "Zahid Hasan", Semester="8th", Credits= 18},
				new Student { Id= 5, Name= "Shafiqul Islam", Semester="6th", Credits= 15},
				
			};

            return lstStudents;
        }


    }


    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Semester { get; set; }
        public int Credits { get; set; }
    }

}

In Deafult.aspx.cs file, you must see I have created a Page Method which is annoted by WebMethod. This method returns a list of Students object.

Default.aspx


<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebMathodAngular.Default" %>




    
Id Name Credit Semester
{{student.id}} {{student.name}} {{student.credits}} {{student.semester}}

Look at the page, here I add ng-controller and ng-app and ng-repeat. If you have little idea about angularJs, you must understand the page. Now just run the application and you will get following output.

Output

*If you don’t clear in any portion or any suggestion, please leave your comment here. To run the application download required packages.

Introduction to AngularJs and Bootstrap in ASP.NET Web form

Revolution just arrived. Client side development is getting easier and cheaper. AngularJs is one of the client side development JavaScript framework. It is developed by google. Website designing also get easier due to emerge of bootstrap. Now let’s introduce AngularJS and Bootstrap in a asp.net web form application. Here I used visual studio 2012 as an IDE.

Step 1: Create a ASP.NET Web Forms Application

Open visual studio, Got to File->New->Project
Select Template -> Visual C# -> Web -> ASP.NET Empty web application, set location and click OK

Step 2: Install required packages

Run the following command in Package Manager Console (Tools->Library Package Manager->Package Manager Console) to install required package. Make sure your internet connection is enabled.

PM> Install-Package AngularJS.Core
PM> Install-Package AngularJS.Resource
PM> Install-Package bootstrap

Step 3: Design Master Page

Add required references for bootstrap and AngularJS , and design master page using bootstrap as follows.
You can use theme. For details visit the article “ Easy way to design web layout by bootstrap theme


<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="AngularWeb.Site" %>





    

    
    

    
    


    
    

Here you must see that I used the reference of app.js, data.js. studentCtrl.js which are not defined yet. Soon, I will create those files.

Step 4: Create Application module, data and angular controller
Create app.js, data.js and studentCtrl.js in scripts -> app folder. Content are given below.

app.js

var app = angular.module('app', ['ngResource']);

data.js

app.value('studentInfo', [
  { id: 1, name: 'Mahedee Hasan', credit:20, semester: '8th' },
  { id: 2, name: 'Enamul Haque', credit: 15, semester: '7th' },
  { id: 2, name: 'Arefin Billah', credit: 15, semester: '6th' },
  { id: 3, name: 'Zahid Hasan', credit: 12, semester: '7th' }
]);

studentCtrl.js

app.controller('studentsCtrl', function ($scope, studentInfo) {
    $scope.studentInfo = studentInfo;
});

App.js for just declaring application module, data.js for hardcoded data by javascript and studentCtrl.js is the main angular controller.

Step 4: Create a Page for View

Create a page name Default.aspx, just right click on the application -> Add -> New item -> Web form using master page. Select Master page and type page name as Default.aspx. Now modify the page as follows.


<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AngularWeb.Default" %>




 
   
Id Name Credit Semester
{{student.id}} {{student.name}} {{student.credit}} {{student.semester}}

Look at the page, here I add ng-controller and ng-app and ng-repeat. If you have little idea about angularJs, you must understand the code. Now just run the application and you will get following output. Happy programming.

Output

*If you don’t clear in any portion or any suggestion, please leave your comment here. To run the application download required packages.

Simple notifications with toastr

toastr is a simple JavaScript toast notification library that is small, easy to use, and extendable. It is mostly used to show notification and its outlook is very nice and responsive. It allows you to create simple toasts with HTML5 and JavaScript like following:

1

Let’s use toastr in a simple asp.net MVC application.

Step 1: Create a ASP.NET MVC application with basic template

Open visual studio, Go to File->New->Project
Select Template -> Visual C# -> Web -> ASP.NET MVC 4 Web application and click OK
Select Basic Template and Razor as view engine

Step 2: Install required packages

Run the following command in package manager console to install packages

PM> Install-Package toastr

Step 3: Create HomeController and index view

Create a Home controller by right click on controller folder. Create an index view in Views -> Home -> Index.cshtml by right clicking in index action of Home controller.

HomeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Toastr.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }

    }
}

Index.cshtml


@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

Toastr Implimentation

Step 5: Modify BundleConfig.cs

BundleConfig.cs


using System.Web;
using System.Web.Optimization;

namespace Toastr
{
    public class BundleConfig
    {
        // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                        "~/Scripts/jquery-ui-{version}.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.unobtrusive*",
                        "~/Scripts/jquery.validate*"));

            //Added for toaster
            bundles.Add(new ScriptBundle("~/bundles/toastr").Include(
                       "~/Scripts/toastr.js*",
                       "~/Scripts/toastrImp.js"));


            // Use the development version of Modernizr to develop with and learn from. Then, when you're
            // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                        "~/Scripts/modernizr-*"));

            //Modify for toastr
            bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css",
                                                                "~/Content/toastr.css"));

            bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
                        "~/Content/themes/base/jquery.ui.core.css",
                        "~/Content/themes/base/jquery.ui.resizable.css",
                        "~/Content/themes/base/jquery.ui.selectable.css",
                        "~/Content/themes/base/jquery.ui.accordion.css",
                        "~/Content/themes/base/jquery.ui.autocomplete.css",
                        "~/Content/themes/base/jquery.ui.button.css",
                        "~/Content/themes/base/jquery.ui.dialog.css",
                        "~/Content/themes/base/jquery.ui.slider.css",
                        "~/Content/themes/base/jquery.ui.tabs.css",
                        "~/Content/themes/base/jquery.ui.datepicker.css",
                        "~/Content/themes/base/jquery.ui.progressbar.css",
                        "~/Content/themes/base/jquery.ui.theme.css"));

            
            BundleTable.EnableOptimizations = false;


        }
         

    }
}

Add toastrImp.js in Scripts folder. Modify BundleConfig.cs to add toastr.js, toastrImp.js and toastr.css add bundle reference in Views->Shared->_Layout.cshtml. toastrImp.js is my created javascript file to implement toastr.

toastrImp.js


$(document).ready(function () {

    displayToastr();
 
});

function displayToastr() {
    //alert('yes');
    // Display a info toast, with no title
    toastr.info('Hi Mahedee, This information for you.')

    // Display a warning toast, with no title
    toastr.warning('Hi Mahedee, This the first warning for you!')

    // Display a success toast, with a title
    toastr.success('Yes! You have successfully completed your task!', 'Congratulation for you, Mahedee!')

    // Display an error toast, with a title
    toastr.error('An error occured in the solution!', 'Please contact with system administrator.')
}

_Layout.cshtml





    
    
    @ViewBag.Title
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")


    @RenderBody()

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/toastr")
    @RenderSection("scripts", required: false)



Now run the program, you will see some notification nicely like below.

Output2

Some option need to know:

The position of toastr can be

1. toast-top-right
2. toast-top-left
3. toast-bottom-right
4. toast-bottom-left
5. toast-top-full-width
6. toast-bottom-full-width

You can change it in toastr.js like following.


toastr.options = {
"closeButton": false,
"debug": false,
"positionClass": "toast-top-full-width",
"onclick": null,
"showDuration": "200",
"hideDuration": "1500",
"timeOut": "6000",
"extendedTimeOut": "1200",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
}

A SignalR Application for real time notification using AngularJS and toastr

SignalR is a new developer’s API provided for ASP.NET web applications, used to add “real time” web functionality to ASP.NET applications. “Real Time” web functionality is the ability to have server code to push contents to connected clients.

Uses
1. Notification
2. Chat application
3. Real time monitoring application
4. Job progress update etc.

So, let’s start to create a SignalR Application. In this program I will assign a task for a person and everybody will get notification.

Step 1: Create a ASP.NET MVC application with basic template

Open visual studio, Got to File->New->Project
Select Template -> Visual C# -> Web -> ASP.NET MVC 4 Web application and click OK
Select Basic Template and Razor as view engine

Step 2: Install required packages
Install nuget package for SignalR. To install click right button of the project and then click Manages NuGet packages. Search SignalR and then install Microsoft SignalR as follows.

installNuget

Run the following command in package manager console to install packages

PM> Install-Package angularjs
PM> Install-Package toastr

Step 3: Create Startup class

Create a Startup class in project root directory. Create Stratup.cs file and modify as follows.

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(SignalRApp.Startup))]

namespace SignalRApp
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

Step 4: Create signalR hub

Create a SignalR hub name NotificationHub in root directory and inherit Hub class. Modify the class as follows

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SignalRApp
{
    
    [HubName("notification")]
    public class NotificationHub : Hub
    {
         public void PushNotification(string msg)
         {
             Clients.All.response(msg);
         }
    }
}

Here Clients.All means all user will get notification. It can be configured on the basis of group and individual.

Step 5: Create HomeController and index view

Create a Home controller by right click on controller folder. Create an index view in Views->Hoome->index.cshtml by right clicking in index action of Home controller.

HomeController.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace SignalRApp.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }

    }
}

Index.cshtml


@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

Please entry a task

Enter a Task:

Here mainController and sendMessage() is declared. I will define it later.

Step 6: Change bundle config

Change BundleConfig and add customScripts, angular, signalr, jquery, toastr buddle as follows.


    public class BundleConfig
    {
        // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new ScriptBundle("~/bundles/customScripts").Include(
                      "~/Scripts/Application/app.js",
                      "~/Scripts/Application/mainController.js"));


            bundles.Add(new ScriptBundle("~/bundles/angular").Include(
                       "~/Scripts/angular.js"));

            bundles.Add(new ScriptBundle("~/bundles/signalr").Include(
                       "~/Scripts/jquery.signalR-2.1.2.js"));

                        
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                        "~/Scripts/jquery-ui-{version}.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.unobtrusive*",
                        "~/Scripts/jquery.validate*"));


            bundles.Add(new ScriptBundle("~/bundles/toastr").Include(
                        "~/Scripts/toastr.js*"));

            // Use the development version of Modernizr to develop with and learn from. Then, when you're
            // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                        "~/Scripts/modernizr-*"));

            //bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));

            bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
                        "~/Content/themes/base/jquery.ui.core.css",
                        "~/Content/themes/base/jquery.ui.resizable.css",
                        "~/Content/themes/base/jquery.ui.selectable.css",
                        "~/Content/themes/base/jquery.ui.accordion.css",
                        "~/Content/themes/base/jquery.ui.autocomplete.css",
                        "~/Content/themes/base/jquery.ui.button.css",
                        "~/Content/themes/base/jquery.ui.dialog.css",
                        "~/Content/themes/base/jquery.ui.slider.css",
                        "~/Content/themes/base/jquery.ui.tabs.css",
                        "~/Content/themes/base/jquery.ui.datepicker.css",
                        "~/Content/themes/base/jquery.ui.progressbar.css",
                        "~/Content/themes/base/jquery.ui.theme.css"));

            bundles.Add(new StyleBundle("~/Content/css").Include(
               //"~/Content/bootstrap.css",
               "~/Content/toastr.css",
               "~/Content/site.css"));


            BundleTable.EnableOptimizations = false;
        }
    }

Here I add app.js and mainController.js in customScripts bundle. I will add it later.
And add bundle reference and ng-app in Views->Shared->_Layout.cshtml

_Layout.cshtml





    
    
    @ViewBag.Title
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")


    @RenderBody()

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/toastr")
    @Scripts.Render("~/bundles/signalr")
    
    @Scripts.Render("~/bundles/angular")
    @Scripts.Render("~/bundles/customScripts")
    
    @RenderSection("scripts", required: false)



Step 7: Add app.js and mainController.js in Scripts->Application folder

App.js


(function () {
    angular.module('app', []);

    $(function () {
        $.connection.hub.logging = true;
        $.connection.hub.start();
    });


    $.connection.hub.error(function (err) {
        console.log('An error occurred: ' + err);
    });

    angular.module('app')
       .value('notification', $.connection.notification)
       .value('toastr', toastr);

})();

mainController.js

angular.module('app').controller('mainController', function ($scope, notification, toastr) {
    $scope.messages = [];

    $scope.sendMessage = function () {
        var inputval = taskForm.elements.txtTask.value;
        taskForm.elements.txtTask.value = "";
        notification.server.pushNotification(inputval);
        $scope.newMessage = "";
    };

    notification.client.response = function onNewMessage(message) {
        displayMessage(message);
        $scope.$apply();
    };

    function displayMessage(message) {
        toastr.success(message); //To nofiy as fadin and fadout
    }

});

Now run the application and write a text in text box, open two or three browser, you will get same notification like below.

output

Thanks for your patient !

Determine whether Caps Lock is ON in ASP.net Page by JavaScript

Here I used a simple Textbox in ASP.net page and used Javascript to determine whether Caps Lock is on or off.
I have used the following Javascript code in between head  tag.
function isCapslock(e) {

            e = (e) ? e : window.event;

            var charCode = false;

            if (e.which) {
                charCode = e.which;
            } else if (e.keyCode) {
                charCode = e.keyCode;
            }

            var shifton = false;
            if (e.shiftKey) {
                shifton = e.shiftKey;
            } else if (e.modifiers) {
                shifton = !!(e.modifiers & 4);
            }

            if (charCode >= 97 && charCode <= 122 && shifton) {
                document.getElementById("txtCapsMsg").value = "Caps Lock is on";
                return true;
            }

            if (charCode >= 65 && charCode <= 90 && !shifton) {
                document.getElementById("txtCapsMsg").value = "Caps Lock is on";
                return true;
            }

            document.getElementById("txtCapsMsg").value = "Caps Lock is off";
            return false;

        }

I have also used two text box in ASP.net page. One for input and another for displaying message whether Caps Lock is on or off.

Message :
Input Text :

Now input some text in input textbox. Message will be showed in txtCapsMsg, textbox whether Caps Lock is on or off.