Visual Studio 2017 start debugging very slow
After some additional investigation I found this thread Unchecking Enable Diagnostic Tools while debugging in Tools → Options → Debugging → General did the trick!
Web Application > right click to go to the Properties > Configuration Properties > Debugging
Remove all items in the folder: C:\Users\manhnguyenv\AppData\Local\Microsoft\WebsiteCache
You will learn:
- ASP.NET MVC 5: Using native ASP.NET MVC
- HTML Form tag
- Model validation in ASP.NET MVC
- Unobtrusive JavaScript
- Unobtrusive Client Validation in ASP.NET MVC 3 in Brad Wilson's blog
- Validation with the Data Annotation Validators and Microsoft.jQuery.Unobtrusive.Validation
- using System.ComponentModel;
- using System.ComponentModel.DataAnnotations;
- Nuget: Install-Package Microsoft.jQuery.Unobtrusive.Ajax
- How jQuery call AJAX
- Using jQuery .on() and .off()
- AJAX error handling with jQuery
- jQuery BlockUI Plugin
- Serialize a HTML Form to a JavaScript Object
- Example: JavaScript serialize a form as JSON
- Second example: https://jsfiddle.net/gabrieleromanato/bynaK/
- Boostrap Modal
- How to use jQuery plugin
- jQuery plugin
- jQuery plugin
- Multi languages
1) Model
using System.ComponentModel; using System.ComponentModel.DataAnnotations; namespace CURDCodeFirst.Models { public class StudentViewModel { public long Id { get; set; } [Required(ErrorMessage = "First Name is required")] [DisplayName("First Name")] [StringLength(255)] public string FirstName { get; set; } [Required(ErrorMessage = "Last Name is required")] [DisplayName("Last Name")] [StringLength(255)] public string LastName { get; set; } public string Name { get; set; } [DataType(DataType.EmailAddress)] [EmailAddress] [Required(ErrorMessage = "Email is required")] public string Email { get; set; } [DisplayName("Enrollment No")] [Required(ErrorMessage = "Enrollment No is required")] public string EnrollmentNo { get; set; } [DisplayName("Phone Number")] [DataType(DataType.PhoneNumber)] [Phone] public string PhoneNumber { get; set; } [DisplayName("Age")] [Range(18, 99, ErrorMessage = "Age should be between 18 and 99")] public int Age { get; set; } } }
2) View
Index.html
@model IEnumerable<StudentViewModel>
@using CURDCodeFirst.Models
@using CURDCodeFirst.Code
<div class="panel panel-primary">
<div class="panel-heading panel-head">Students</div>
<div class="panel-body">
<div class="btn-group">
<a id="createEditStudentModal" data-toggle="modal" href="@Url.Action("AddEditStudent")" data-target="#modal-action-student" class="btn btn-primary">
<i class="glyphicon glyphicon-plus"></i> Add Student
</a>
</div>
<div class="top-buffer"></div>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Enrollment No</th>
<th>Email</th>
<th>Phone Number</th>
<th>Age</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.Name</td>
<td>@item.EnrollmentNo</td>
<td>@item.Email</td>
<td>@item.PhoneNumber</td>
<td>@item.Age</td>
<td>
<a id="editUserModal" data-toggle="modal" href="@Url.Action("AddEditStudent", new {id=@item.Id })" data-target="#modal-action-student" class="btn btn-info">
<i class="glyphicon glyphicon-pencil"></i>
</a>
<a id="deleteUserModal" data-toggle="modal" href="@Url.Action("DeleteStudent", new {id=@item.Id })" data-target="#modal-action-student" class="btn btn-danger">
<i class="glyphicon glyphicon-trash"></i>
</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
@Html.Partial("_Modal", new BootstrapModel { Id = "modal-action-student", AreaLabeledId = "modal-action-student-label", Size = ModalSize.Medium })
@section scripts{
@Scripts.Render("~/Scripts/student-index.js")
}
_AddEditStudent.cshtml
@using CURDCodeFirst.Models
@model StudentViewModel
@using (Html.BeginForm())
{
@Html.HiddenFor(model => model.Id)
@Html.Partial("_ModalHeader", new ModalHeader { Heading = $"{(Model.Id == 0 ? "Add" : "Edit")} Student" })
<div class="modal-body form-horizontal">
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(model => model.FirstName, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.FirstName, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.FirstName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LastName, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.LastName, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.LastName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.EnrollmentNo, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.EnrollmentNo, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.EnrollmentNo)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Email, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.Email, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.Email)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PhoneNumber, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.PhoneNumber, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.PhoneNumber)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Age, new { @class = "col-lg-3 col-sm-3 control-label" })
<div class="col-lg-6">
@Html.TextBoxFor(model => model.Age, new { @class = "form-control " })
@Html.ValidationMessageFor(model => model.Age)
</div>
</div>
</div>
@Html.Partial("_ModalFooter", new ModalFooter())
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/common.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/student-addeditstudent.js")" type="text/javascript"></script>
}
JavaScript
common.js
(function ($) { $.fn.serializeFormJSON = function () { var o = {}; var a = this.serializeArray(); $.each(a, function () { if (o[this.name]) { if (!o[this.name].push) { o[this.name] = [o[this.name]]; } o[this.name].push(this.value || ''); } else { o[this.name] = this.value || ''; } }); return o; }; })(jQuery);
Student-Index.js
(function ($) { function Student() { var $this = this; function initilizeModel() { console.log('Init the model and show in the bootstrap modal'); $("#modal-action-student").on('loaded.bs.modal', function (e) { console.log('Show bootstrap modal'); }).on('hidden.bs.modal', function (e) { console.log('Hide bootstrap modal'); $(this).removeData('bs.modal'); }); } $this.init = function () { initilizeModel(); } } $(function () { var self = new Student(); self.init(); }); }(jQuery))
Student-AddEditStudent.js
$(document).ready(function () { var $form = $("form"); $form.validate(); $(document).on("submit", $form, function (e) { e.preventDefault(); if ($form.validate().valid) { var data = $form.serializeFormJSON(); $.ajax({ url: "/Student/SaveStudent", type: "POST", dataType: "json", data: JSON.stringify(data), contentType: "application/json; charset=utf-8", /* * A function to be called if the request fails. */ error: function (jqXhr, textStatus, errorThrown) { alert('An error occurred... Look at the console (F12 or Ctrl+Shift+I, Console tab) for more information!'); console.log('jqXHR:' + jqXhr); console.log('jqXHR.responseText:' + jqXhr.responseText); console.log('status:' + jqXhr.status); console.log('status code:' + jqXhr.statusCode); console.log('status text:' + jqXhr.statusText); console.log('textStatus:' + textStatus); console.log('errorThrown:' + errorThrown); }, /* * A function to be called if the request succeeds. */ success: function (data, textStatus, jqXhr) { alert('Call AJAX successfully. Look at the console (F12 or Ctrl+Shift+I, Console tab) for more information! '); console.log('jqXHR:' + jqXhr); console.log('textStatus:' + textStatus); console.log('data:' + data); } }); } }); });
3) Controller
using CF.Data;
using CF.Repo;
using CURDCodeFirst.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Mvc;
using System.Net.Http;
namespace CURDCodeFirst.Controllers
{
public class StudentController : Controller
{
private readonly Repository _studentRepository;
public StudentController()
{
var unitOfWork = new UnitOfWork();
_studentRepository = unitOfWork.Repository();
}
[HttpGet]
public ActionResult Index()
{
IEnumerable students = _studentRepository.Table.AsEnumerable().Select(s => new StudentViewModel
{
Id = s.Id,
Name = $"{s.FirstName} {s.LastName}",
Email = s.Email,
EnrollmentNo = s.EnrollmentNumber,
PhoneNumber = s.PhoneNumber,
Age = s.Age
});
return View(students);
}
[HttpGet]
public PartialViewResult AddEditStudent(long? id)
{
StudentViewModel model = new StudentViewModel();
if (id.HasValue)
{
Student student = _studentRepository.GetById(id.Value);
model.Id = student.Id;
model.FirstName = student.FirstName;
model.LastName = student.LastName;
model.EnrollmentNo = student.EnrollmentNumber;
model.Email = student.Email;
model.PhoneNumber = student.PhoneNumber;
model.Age = student.Age;
}
return PartialView("~/Views/Student/_AddEditStudent.cshtml", model);
}
[HttpPost]
public JsonResult SaveStudent(StudentViewModel model)
{
try
{
if (ModelState.IsValid)
{
long id = model.Id;
bool isNew = id == 0;
Student student = isNew ? new Student
{
AddedDate = DateTime.UtcNow
} : _studentRepository.GetById(id);
student.FirstName = model.FirstName;
student.LastName = model.LastName;
student.EnrollmentNumber = model.EnrollmentNo;
student.Email = model.Email;
student.PhoneNumber = model.PhoneNumber;
student.Age = model.Age;
student.IPAddress = Request.UserHostAddress;
student.ModifiedDate = DateTime.UtcNow;
string msg;
if (isNew)
{
_studentRepository.Insert(student);
msg = "Add success";
}
else
{
_studentRepository.Update(student);
msg = "Update success";
}
return Json(msg, JsonRequestBehavior.AllowGet);
}
return Json("ModelState is not valid", JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(ex.Message, JsonRequestBehavior.AllowGet);
}
}
}
}