What is Unobtrusive Validation?

In a normal validation scenario, when we use a validator to validate any control and use Client side validation, some JavaScript is generated and rendered as HTML. Also some supportive JavaScript files also get loaded by the browser for the validation.

Now with feature Unobtrusive Validation, inline JavaScript is not generated and rendered to handle the Client Side validation. Instead of this, it uses HTML5 data-* attributes for all these validation.

S0 now let’s see a normal scenario. I have taken textbox and applied two ASP.NET validators on it. One is RequiredFieldValidator and RangeValidator that allows to enter the value between 100 and 1000. Let’s see the aspx code:


Đọc dữ liệu từ Excel

Mã nguồn dưới đây hướng dẫn cách đọc dữ liệu từ Excel vào cơ sở dữ liệu

var fullFileName =”PathOfExcelFile”;
var connectionString = string.Format(“Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 8.0;data source={0};”, fullFileName);
var adapter = new OleDbDataAdapter(“select * from [Ten_Sheet$]”, connectionString);
var ds = new DataSet();
string tableName = “tableName”;
adapter.Fill(ds, tableName);
DataTable data = ds.Tables[tableName];
dataGridView1.DataSource = data;

Export to excel C#- Xuất dữ liệu ra excel bằng c#

Mã nguồn dưới đây hướng dẫn cách xuất dữ liệu ra excel trong C#

public void ExportToExcel(DataTable dataTable, string ExcelFilePath)
int ColumnsCount;

if (DataTable == null || (ColumnsCount = dataTable.Columns.Count) == 0)
throw new Exception(“ExportToExcel: Null or empty input table!\n”);

// create a new workbook
Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();

object misValue = System.Reflection.Missing.Value;

// single worksheet
Microsoft.Office.Interop.Excel._Worksheet Worksheet = (Microsoft.Office.Interop.Excel._Worksheet)Excel.ActiveSheet;

object[] Header = new object[ColumnsCount];

// column headings
for (int i = 0; i < ColumnsCount; i++)
Header[i] = dataTable.Columns[i].ColumnName;

Microsoft.Office.Interop.Excel.Range HeaderRange = Worksheet.get_Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[1, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[1, ColumnsCount]));
HeaderRange.Value2 = Header;
HeaderRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray);
HeaderRange.Font.Bold = true;

// DataCells
int RowsCount = dataTable.Rows.Count;
object[,] Cells = new object[RowsCount, ColumnsCount];

for (int j = 0; j < RowsCount; j++)
for (int i = 0; i < ColumnsCount; i++)
Cells[j, i] = dataTable.Rows[j][i];

Worksheet.get_Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[2, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[RowsCount + 1, ColumnsCount])).Value2 = Cells;

// check fielpath
if (ExcelFilePath != null && ExcelFilePath != “”)
Worksheet.SaveAs(ExcelFilePath, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue);

Excel.Visible = true;
catch (Exception ex)
throw new Exception(“ExportToExcel: Excel file could not be saved! Check filepath.\n”
+ ex.Message);
else // no filepath is given
Excel.Visible = true;
catch (Exception ex)
throw new Exception(“ExportToExcel: \n” + ex.Message);

Gọi hàm ExportToExcel()

ExportToExcel(table, fileOnDisk);

What is a Data Dictionary?

A Data Dictionary, also called a Data Definition Matrix, provides detailed information about the business data, such as standard definitions of data elements, their meanings, and allowable values. While a conceptual or logical Entity Relationship Diagram will focus on the high-level business concepts, a Data Dictionary will provide more detail about each attribute of a business concept.

Essentially, a data dictionary provides a tool that enables you to communicate business stakeholder requirements in such a way that your technical team can more easily design a relational database or data structure to meet those requirements. It helps avoid project mishaps such as requiring information in a field that a business stakeholder can’t reasonably be expected to provide, or expecting the wrong type of information in a field.

The Key Elements of a Data Dictionary

A Data Dictionary provides information about each attribute, also referred to as fields, of a data model. An attribute is a place in the database that holds information. For example, if we were to create a Data Dictionary representing the articles here on Bridging the Gap, we’d potentially have attributes for article title, article author, article category, and the article content itself.

A Data Dictionary is typically organized in a spreadsheet format. Each attribute is listed as a row in the spreadsheet and each column labels an element of information that is useful to know about the attribute.

Let’s look at the most common elements included in a data dictionary.

  • Attribute Name – A unique identifier, typically expressed in business language, that labels each attribute.
  • Optional/Required – Indicates whether information is required in an attribute before a record can be saved.
  • Attribute Type – Defines what type of data is allowable in a field. Common types include text, numeric, date/time, enumerated list, look-ups, booleans, and unique identifiers.

While these are the core elements of a data dictionary, it’s not uncommon to document additional information about each element, which may include the source of the information, the table or concept in which the attribute is contained, the physical database field name, the field length, and any default values.

ASP.NET MVC – Sử dụng DataTable

Dưới đây là hướng dẫn cách sử dụng DataTable 

How to Install DataTable

Bước 1 – Thay đổi trong _Layout.cshtml

Mở _layout.cshtml và bổ sung phần sau trong phần


@RenderSection(“css”, false)


Trước thẻ </body> bổ sung thêm đoạn mã sau

@RenderSection(“scripts”, required: false)

Bước 2 – Thêm mã trong index.cshtml

Thiết lập ID cho bảng và class

<table class=”display” id=”table_id”>



Phần heading của bảng phải để trong <thead>

Phần nội dung hiển thị dữ liệu phải khai báo trong phần <tbody>


@foreach (var item in Model)


Bước 3 – Chèn thêm đoạn code sau trong phần view

@section scripts



$(document).ready(function () {




@section css


<link rel=”stylesheet” type=”text/css” href=”//cdn.datatables.net/1.10.12/css/jquery.dataTables.css”>


ASP.NET MVC Search and Paging

Đoạn code dưới đây hướng dẫn cách thiết lập chức năng Search & Paging (tìm kiếm và phân trang) trong asp.net mvc:

1. Install PageList

  • Click chuột phải trên Project và chọn Manage NuGet Packages…
  • Gõ tìm PagedList.mvc
  • Click chọn và Install để cài đặt thư viện vào project

3. Controller

public ActionResult Index(string searchString, int? page)
int recordsPerPage = 5;

if (!page.HasValue)
page = 1; // set initial page value
ViewBag.Keyword = searchString;

var products = db.Products.ToList();
if (!String.IsNullOrEmpty(searchString))
products = products.Where(s => s.ProductName.Contains(searchString)).ToList();
catch (Exception ex) { }
products.OrderByDescending(v => v.ProductId);

var finalList = products.ToPagedList(page.Value, recordsPerPage);
return View(finalList);

3. View

Sửa View index để mã như sau, chép từ đầu và ghi đè thay thế code trong view từ đầu đến ngay trước <table class=”table”>

@using PagedList;
@using PagedList.Mvc;
@model IPagedList<DataAccessDemoApp.Models.Product>
ViewBag.Title = “Index”;
@Html.ActionLink(“Create New”, “Create”)
@using (Html.BeginForm(“Index”, “Products”, FormMethod.Get))
Find by name: <input type=”text” name=”searchString” value=”@ViewBag.Keyword” />
<input type=”submit” value=”Search” />
<table class=”table”>

Chèn thêm đoạn sau vào cuối view Index.cshtml

@Html.PagedListPager(Model, page => Url.Action(“Index”, new
searchString = ViewBag.Keyword

Nhấn F5 để chạy thử và kiểm tra kết quả.

Custom route in ASP.NET MVC

Đoạn code dưới đây hướng dẫn cách định nghĩa Custom Route trong ASP.NET MVC

Để định nghĩa route mới, vào file ~/App_Start/RouteConfig.cs và định nghĩa route mới ngay sau dòng lệnh routes.IgnoreRoute

public class RouteConfig
        public static void RegisterRoutes(RouteCollection routes)

                name: "Admin",
                url: "Admin/{action}/{id}",
                defaults: new { controller = "Admin", action = "Create", id
= UrlParameter.Optional }

                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id =
UrlParameter.Optional }

Lưu ý: là Route mặc định luôn để cuối cùng sau tất cả các route khác, nếu để route mặc định lên đầu tiên thì các route định nghĩa sau route default sẽ không được thực hiện.