Showing posts with label ASP.NET MVC. Show all posts
Showing posts with label ASP.NET MVC. Show all posts

Monday, 22 June 2015

Upload and Delete File(s) using jQuery Multifile library in ASP.Net MVC

In this article I am going to demonstrate about multiple file upload and delete in asp.net mvc application by using jquery.multifile and jquery.form library.

You can easily upload and delete the single or multiple files in a single hit of server and no need to call server function in each and every upload or delete of files.

Download Source Code

Here I am taking one scenario as an example. Suppose we have Product information in a table and we want to upload multiple files for a single product.

 

1)      In this case we need two tables one is related to Product and other is related to Product Files. Let’s first create these two tables in database (sql script is given in project source code).

 

2)      Open Microsoft Visual Studio

3)      Create a new asp.net mvc empty application and choose razor view engine to implement this example.

4)      Download the following packages and include in your application.

a)      jQuery

b)      Bootstrap (optional)

c)       jquery.multifile

d)      jquery.form

5)      Add ADO.Net Entity Data Model for selecting the database tables (Product and Product File) in Models folder. It will generate .edmx in your application. This is called Database First Approach in Entity Framework.

6)      Now create a _Layout.cshtml (master page) in Views/Shared folder and add reference of these files.

<html>

<head>

    <meta name="viewport" content="width=device-width" />

    <title>@ViewBag.Title</title>

    <link href="~/Content/bootstrap.min.css" rel="stylesheet" />

    <link href="~/Content/bootstrap-theme.min.css" rel="stylesheet" />

    <link href="~/Content/style.css" rel="stylesheet" />

    <script src="~/Scripts/jquery-2.1.4.min.js"></script>

    <script src="~/Scripts/jquery.MultiFile.js"></script>

    <script src="~/Scripts/jquery.form.js"></script>

    <script src="~/Scripts/app.js"></script>

</head>

<body>

    <div class="container">

        @RenderBody()

    </div>

</body>

</html>

7)      Now create a ProductController in controller folder in order to render following views:

a)      Index (To display the list of the products)

b)      Create (To create a new product)

c)       Edit (To edit and update the existing product info)

d)      Details (To view to details of existing product)

e)      Delete (To Delete the existing Product)

 

8)      Add an Index action and a View (view available in project source code):

 public ActionResult Index()

        {

            using (ProductEntities db = new ProductEntities())

            {

                return View(db.Product.ToList());

            }

        }

9)      Add a Create action (GET & POST) and its View (view available in project source code):

 public ActionResult Create()

        {

            return View();

        }

 

        [HttpPost]

        public ActionResult Create(Product model, HttpPostedFileBase[] files)

        {

            bool success = false;

            string message = "";

 

            if (ModelState.IsValid)

            {

                using (ProductEntities db = new ProductEntities())

                {

                    db.Product.Add(model);

                    db.SaveChanges();

 

                    if (files != null && files.Length > 0)

                    {

                        foreach (var file in files)

                        {

                            if (file != null)

                            {

                                SaveFile(file, String.Format("~/content/product/{0}/", model.ProductID));

 

                                ProductFile fileObj = new ProductFile

                                {

                                    ProductID = model.ProductID,

                                    FileName = file.FileName

                                };

 

                                db.ProductFile.Add(fileObj);

                            }

                        }

                        db.SaveChanges();

                    }

 

                    success = true;

                    message = "Product saved successfully.";

                }

            }

            else

            {

                message = "Model State is not valid.";

            }

 

            return Json(new { success = success, message = message, callbackurl = Url.Action("Index") });

        }

10)   Same way you can add Edit, Detail and Delete actions and its view.

11)   There is two common functions (Save & Delete) for upload and delete of file is also available in Product controller.

        #region Save and Delete File Function

 

        private string SaveFile(HttpPostedFileBase httpfile, string directory, string filename = null)

        {

            if (httpfile != null && httpfile.ContentLength > 0)

            {

                string fileName = filename ?? httpfile.FileName;

 

                if (!System.IO.Directory.Exists(Server.MapPath(directory)))

                {

                    System.IO.Directory.CreateDirectory(Server.MapPath(directory));

                }

 

                string filePath = System.IO.Path.Combine(String.Format("{0}{1}", Server.MapPath(directory), fileName));

                httpfile.SaveAs(filePath);

                return String.Format("{0}{1}", directory, fileName);

            }

 

            return "";

        }

 

        private void DeleteFile(string filepath)

        {

            if (System.IO.File.Exists(Server.MapPath(filepath)))

            {

                System.IO.File.Delete(Server.MapPath(filepath));

            }

        }

 

        #endregion

 

If you run an application, the output should be something like below screenshot:


You can add, edit, view and delete the product and its files as well.

Edit Product screenshot is given below:

Thanks for reading this article. The missing action and view is available in project source. If you have any question and doubt you can freely ask me and do not forget to give your valuable comments.

Download Source Code

 

Tuesday, 24 February 2015

CRUD using MVC Web API and AngularJS

In this article I am going to demonstrate about how can we create basic crud (create, read, update and delete) using MVC Web API, SQL Server and Angular JS.

In this demo application our main concern will be on Angular JS data-binding and routing. I also used a Entity Framework Code First approach for database operation.

Functionalities present in this application:

a)      Data Binding using Angularjs

b)      Client side routing using Angular Routing

c)       Cascading Dropdown using AngularJS

d)      Conditional formatting using Angularjs

e)      Select, Insert, Update and Delete record in sql server database.

Let’s start step by step so that we can achieve our objective at the end of this article. After completing this demo our application should look like this:

1)       Employee List page:

2)      Employee Page for Create and Edit a record.

3)      Employee Delete Confirmation page with details:

 

To achieve the above, follow the steps given below:

1)      Create a new asp.net mvc empty web application.

2)      Add the following package in your application:

a)      AngularJS.Core

b)      AngularJS.Route

c)       Bootstrap

d)      EntityFramework

3)      Create a Model named Employee in Models folder and replace the code with the following:

 

    public class Employee

    {

        public int EmployeeId { get; set; }

 

        [Required]

        [StringLength(20)]

        public string FirstName { get; set; }

 

        [Required]

        [StringLength(20)]

        public string LastName { get; set; }

 

        [Required]

        [StringLength(100)]

        public string Description { get; set; }

 

        public float Salary { get; set; }

 

        [Required]

        [StringLength(50)]

        public string Country { get; set; }

 

        [Required]

        [StringLength(50)]

        public string State { get; set; }

 

        public DateTime DateofBirth { get; set; }

        public bool IsActive { get; set; }

    }

 

    public class EmployeeDbContext : DbContext

    {

        public EmployeeDbContext()

            : base()

        {

            Database.SetInitializer<EmployeeDbContext>(new EmployeeDbContextInitializer());

        }

 

        public DbSet<Employee> Employees { get; set; }

    }

 

    public class EmployeeDbContextInitializer : DropCreateDatabaseIfModelChanges<EmployeeDbContext>

    {

        protected override void Seed(EmployeeDbContext context)

        {

            var list = new List<Employee>

            {

                new Employee { FirstName = "Rohit", LastName = "Kesharwani", Description = "Rohit Kesharwani", DateofBirth = DateTime.Now.AddYears(-23), Country = "IN", State="UP", Salary = 99999, IsActive = true },

                new Employee { FirstName = "Rahul", LastName = "Singh", Description = "Rahul Singh", DateofBirth = DateTime.Now.AddYears(-25), Country = "IN", State="MP", Salary = 49999.28f, IsActive = true }

            };

 

            list.ForEach(m =>

                {

                    context.Employees.Add(m);

                });

 

            context.SaveChanges();

 

            base.Seed(context);

        }

    }

 

4)      Add a connection string with same name of EmployeeDbContext in web.config:

<connectionStrings>

    <add name="EmployeeDbContext" connectionString="Data Source=(local);Initial Catalog=EmpDb;Integrated Security=true;" providerName="System.Data.SqlClient"/>

</connectionStrings>

 

5)      Now create a Employee API controller to perform crud in database:

 

 

public class EmployeeController : ApiController

    {

        EmployeeDbContext db = new EmployeeDbContext();

 

        // GET api/employee

        [ActionName("get"), HttpGet]

        public IEnumerable<Employee> Emps()

        {

            return db.Employees.ToList();

        }

 

        // GET api/employee/5

        public Employee Get(int id)

        {

            return db.Employees.Find(id);

        }

 

        // POST api/employee

        public HttpResponseMessage Post(Employee model)

        {

            if (ModelState.IsValid)

            {

                db.Employees.Add(model);

                db.SaveChanges();

 

                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, model);

                return response;

            }

            else

            {

                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);

            }

        }

 

        // PUT api/employee/5

        public HttpResponseMessage Put(Employee model)

        {

            if (ModelState.IsValid)

            {

                db.Entry(model).State = System.Data.Entity.EntityState.Modified;    

                db.SaveChanges();

 

                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, model);

                return response;

            }

            else

            {

                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);

            }

        }

 

        // DELETE api/employee/5

        public HttpResponseMessage Delete(int id)

        {

            Employee emp = db.Employees.Find(id);

            if (emp == null)

            {

                return Request.CreateResponse(HttpStatusCode.NotFound);

            }

            db.Employees.Remove(emp);

            db.SaveChanges();

 

            return Request.CreateResponse(HttpStatusCode.OK, emp);

        }

 

6)      Also create a Country controller to retrieve country and its states from server side in order to implement cascading dropdown list:

 

public class CountryController : ApiController

    {

        // GET api/country

        public IEnumerable<System.Web.Mvc.SelectListItem> Get()

        {

            List<System.Web.Mvc.SelectListItem> countries = new List<System.Web.Mvc.SelectListItem>

            {

                new System.Web.Mvc.SelectListItem { Text = "India", Value="IN" },

                new System.Web.Mvc.SelectListItem { Text = "United States", Value="US" },

                new System.Web.Mvc.SelectListItem { Text = "United Kingdom", Value="UK" },

                new System.Web.Mvc.SelectListItem { Text = "Australlia", Value="CA" }

            };

 

            return countries;

        }

 

        // GET api/country/5

        public IEnumerable<System.Web.Mvc.SelectListItem> Get(string id)

        {

            List<System.Web.Mvc.SelectListItem> states = new List<System.Web.Mvc.SelectListItem>();

 

            switch (id)

            {

                case "IN":

                    states.Add(new System.Web.Mvc.SelectListItem { Text = "Uttar Pradesh", Value = "UP" });

                    states.Add(new System.Web.Mvc.SelectListItem { Text = "Madhya Pradesh", Value = "MP" });

                    states.Add(new System.Web.Mvc.SelectListItem { Text = "Delhi", Value = "DL" });

                    states.Add(new System.Web.Mvc.SelectListItem { Text = "Kanpur", Value = "KN" });

                    break;

                case "US":

                    states.Add(new System.Web.Mvc.SelectListItem { Text = "California", Value = "CA" });

                    states.Add(new System.Web.Mvc.SelectListItem { Text = "Newyork", Value = "NY" });

                    break;

                case "UK":

                    states.Add(new System.Web.Mvc.SelectListItem { Text = "London", Value = "LN" });

                    states.Add(new System.Web.Mvc.SelectListItem { Text = "Paris", Value = "PR" });

                    break;

                case "CA":

                    states.Add(new System.Web.Mvc.SelectListItem { Text = "Sydney", Value = "SD" });

                    states.Add(new System.Web.Mvc.SelectListItem { Text = "Melbourne", Value = "MB" });

                    break;

            }

 

            return states;

        }

    }

 

7)      Now create a Home controller and add an Index view and reference some css and javascript files of angularjs and bootstrap to create a view and partial views:

public class HomeController : Controller

    {

        public ActionResult Index()

        {

            return View();

        }

    }

 

8)      Index view with js and css references:

 

@{

    Layout = null;

}

 

<!DOCTYPE html>

 

<html ng-app="EmpApp">

<head>

    <meta name="viewport" content="width=device-width" />

    <title>Index</title>

    <link href="@Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />

    <script src="@Url.Content("~/Scripts/angular.min.js")" type="text/javascript"></script>

    <script src="@Url.Content("~/Scripts/angular-route.js")" type="text/javascript"></script>

    <script src="@Url.Content("~/Scripts/app/app.js")" type="text/javascript"></script>

    <script src="@Url.Content("~/Scripts/app/controller.js")" type="text/javascript"></script>

</head>

<body>

    <div class="main container" ng-view>

      

    </div>

</body>

</html>

 

I have highlighted ng-app and ng-view attribute. This is for initializing module under app and rendering of partial views inside ng-view.

9)      Now create an app.js file for configuration of route and controllers. The code of app.js is given below:

var EmpApp = angular.module('EmpApp', [

    'ngRoute',

    'EmpControllers'

]);

 

EmpApp.config(['$routeProvider', function ($routeProvider) {

 

    $routeProvider.when('/list', {

        templateUrl: 'Employee/list.html',

        controller: 'ListController'

    }).

    when('/create', {

        templateUrl: 'Employee/edit.html',

        controller: 'EditController'

    }).

    when('/edit/:id', {

        templateUrl: 'Employee/edit.html',

        controller: 'EditController'

    }).

    when('/delete/:id', {

        templateUrl: 'Employee/delete.html',

        controller: 'DeleteController'

    }).

    otherwise({

        redirectTo: '/list'

    });

 

}]);

 

10)   Now add a folder named Employee under root directory of an application and following three views (html files) list.html, edit.html and delete.html.

a)      List.html

<div>

    <a href="#/create" class="btn">Create</a>

</div>

<div class="table-responsive">

    <table class="table table-striped table-bordered">

        <tr>

            <th>Employee Id</th>

            <th>First Name</th>

            <th>Last Name</th>

            <th>Description</th>

            <th>Salary</th>

            <th>Country</th>

            <th>State</th>

            <th>Date of Birth</th>

            <th>Is Active</th>

            <th></th>

            <th></th>

        </tr>

        <tr ng-repeat="item in employees">

            <td>{{ item.EmployeeId }}</td>

            <td>{{ item.FirstName }}</td>

            <td>{{ item.LastName }}</td>

            <td>{{ item.Description }}</td>

            <td>{{ item.Salary | number: 2 }}</td>

            <td>{{ item.Country }}</td>

            <td>{{ item.State }}</td>

            <td>{{ item.DateofBirth | date }}</td>

            <td>

                <span class="label" ng-class="{true:'label-success', false:'label-danger', '':'hidden'}[item.IsActive]">

                    {{ item.IsActive ? 'Active' : 'In Active' }}</span>

            </td>

            <td>

               <a href="#/edit/{{item.EmployeeId}}" class="glyphicon glyphicon-edit"></a>

            </td>

            <td>

            <a href="#/delete/{{item.EmployeeId}}" class="glyphicon glyphicon-trash"></a>

            </td>

        </tr>

    </table>

</div>

 

b)      Edit.html

<h3>

    {{ title }}</h3>

<hr />

<form role="form" style="max-width: 500px;">

<strong class="error">{{ error }}</strong>

<div class="form-group">

    <label for="firstname">

        First Name</label>

    <input type="text" class="form-control" id="firstname" ng-model="firstname" />

</div>

<div class="form-group">

    <label for="lastname">

        Last Name:</label>

    <input type="text" class="form-control" id="lastname" ng-model="lastname" />

</div>

<div class="form-group">

    <label for="country">

        Country:</label>

    <select class="form-control" id="country" ng-model="country" ng-options="c.Value as c.Text for c in countries" ng-change="getStates()">

        <option value="">-- Select Country --</option>

    </select>

</div>

<div class="form-group">

    <label for="state">

        State:</label>

    <select class="form-control" id="state" ng-model="state" ng-disabled="!states" ng-options="s.Value as s.Text for s in states">

        <option value="">-- Select State --</option>

    </select>

</div>

<div class="form-group">

    <label for="salary">

        Current Salary:</label>

    <input type="text" class="form-control" id="salary" ng-model="salary" />

</div>

<div class="form-group">

    <label for="dob">

        Date of Birth:</label>

    <input type="date" class="form-control" id="dob" ng-model="dob" />

</div>

<div class="form-group">

    <label for="description">

        Description:</label>

    <textarea rows="5" cols="10" class="form-control" id="description" ng-model="description"></textarea>

</div>

<div class="form-group checkbox">

    <label>

        <input type="checkbox" ng-model="active" />Active</label>

</div>

<a href="#/list" class="btn btn-info">Back to List</a>

<button type="submit" class="btn btn-default" ng-click="save()">

    Submit</button>

</form>

 

c)       Delete.html

<h3>

    Are you want to sure to delete this record?</h3>

<hr />

<form class="form-horizontal" style="max-width: 500px;">

<div class="form-group">

    <label class="control-label col-xs-3">

        First Name :</label>

    <div class="col-xs-9">

        <p class="form-control-static">

            {{ firstname }}</p>

    </div>

</div>

<div class="form-group">

    <label class="control-label col-xs-3">

        Last Name :</label>

    <div class="col-xs-9">

        <p class="form-control-static">

            {{ lastname }}</p>

    </div>

</div>

<div class="form-group">

    <label class="control-label col-xs-3">

        Country :</label>

    <div class="col-xs-9">

        <p class="form-control-static">

            {{ country }}</p>

    </div>

</div>

<div class="form-group">

    <label class="control-label col-xs-3">

        State :</label>

    <div class="col-xs-9">

        <p class="form-control-static">

            {{ state }}</p>

    </div>

</div>

<div class="form-group">

    <label class="control-label col-xs-3">

        Salary :</label>

    <div class="col-xs-9">

        <p class="form-control-static">

            {{ salary }}</p>

    </div>

</div>

<div class="form-group">

    <label class="control-label col-xs-3">

        Date of Birth :</label>

    <div class="col-xs-9">

        <p class="form-control-static">

            {{ dob | date }}</p>

    </div>

</div>

<div class="form-group">

    <label class="control-label col-xs-3">

        Description :</label>

    <div class="col-xs-9">

        <p class="form-control-static">

            {{ description }}</p>

    </div>

</div>

<div class="form-group">

    <div class="col-xs-offset-3 col-xs-9">

        <span class="label" ng-class="{true:'label-success', false:'label-danger', '':'hidden'}[active]">

            {{ active ? 'Active' : 'In Active' }}</span>

    </div>

</div>

<div class="form-group">

    <div class="col-xs-offset-3 col-xs-9 text-center">

        <a href="#/list" class="btn btn-info">Back to List</a>

        <button type="submit" class="btn btn-primary" ng-click="delete()">

            Delete</button>

    </div>

</div>

</form>

 

We had setup three views for list, create, edit and delete. Now we will implement the functionalities for these three views.

11)   Create a controller.js file and add the following code given below:

var EmpControllers = angular.module("EmpControllers", []);

 

// this controller call the api method and display the list of employees

// in list.html

EmpControllers.controller("ListController", ['$scope', '$http',

    function ($scope, $http) {

        $http.get('/api/employee').success(function (data) {

            $scope.employees = data;

        });

    } ]

);

 

// this controller call the api method and display the record of selected employee

// in delete.html and provide an option for delete

EmpControllers.controller("DeleteController", ['$scope', '$http', '$routeParams', '$location',

        function ($scope, $http, $routeParams, $location) {

 

            $scope.id = $routeParams.id;

            $http.get('/api/employee/' + $routeParams.id).success(function (data) {

                $scope.firstname = data.FirstName;

                $scope.lastname = data.LastName;

                $scope.country = data.Country;

                $scope.state = data.State;

                $scope.salary = data.Salary;

                $scope.active = data.IsActive;

                $scope.dob = data.DateofBirth;

                $scope.description = data.Description;

            });

 

            $scope.delete = function () {

 

                $http.delete('/api/Employee/' + $scope.id).success(function (data) {

                    $location.path('/list');

                }).error(function (data) {

                    $scope.error = "An error has occured while deleting employee! " + data;

                });

            };

        }

]);

 

// this controller call the api method and display the record of selected employee

// in edit.html and provide an option for create and modify the employee and save the employee record

EmpControllers.controller("EditController", ['$scope', '$filter', '$http', '$routeParams', '$location',

    function ($scope, $filter, $http, $routeParams, $location) {

 

        $http.get('/api/country').success(function (data) {

            $scope.countries = data;

        });

 

        $scope.id = 0;

        $scope.getStates = function () {

            var country = $scope.country;

            if (country) {

                $http.get('/api/country/'+country).success(function (data) {

                    $scope.states = data;

                });

            }

            else {

                $scope.states = null;

            }

        }

 

        $scope.save = function () {

 

            var obj = {

                EmployeeId: $scope.id,

                FirstName: $scope.firstname,

                LastName: $scope.lastname,

                Country: $scope.country,

                State: $scope.state,

                Salary:$scope.salary,

                IsActive: $scope.active,

                Description: $scope.description,

                DateofBirth: $scope.dob

            };

 

            if ($scope.id == 0) {

 

                $http.post('/api/Employee/', obj).success(function (data) {

                    $location.path('/list');

                }).error(function (data) {

                    $scope.error = "An error has occured while adding employee! " + data.ExceptionMessage;

                });

            }

            else {

 

                $http.put('/api/Employee/', obj).success(function (data) {

                    $location.path('/list');

                }).error(function (data) {

                    console.log(data);

                    $scope.error = "An Error has occured while Saving customer! " + data.ExceptionMessage;

                });

            }

        }

 

        if ($routeParams.id) {

 

            $scope.id = $routeParams.id;

            $scope.title = "Edit Employee";

 

            $http.get('/api/employee/' + $routeParams.id).success(function (data) {

                $scope.firstname = data.FirstName;

                $scope.lastname = data.LastName;

                $scope.country = data.Country;

                $scope.state = data.State;

                $scope.salary = data.Salary;

                $scope.active = data.IsActive;

                $scope.description = data.Description;

                $scope.dob = new Date(data.DateofBirth);

 

                $scope.getStates();

            });

        }

        else {

            $scope.title = "Create New Employee";

        }

    }

]);

 

In this controller.js we have multiple controller for different views. Like ListController for list view (display the list of employees), Edit controller for edit view (create and modify the record), DeleteController for delete view (delete confirmation and delete the record).

Now all we have implement and successfully completed all the steps.

To test the process you can build and run an application. I hope it works fine.

Thanks for reading this article. If you have any queries and suggestion please feel free to ask me and also your valuable comments are important for me which motivates me for writing articles.