IIS 7.5 error: Handler “PageHandlerFactory-Integrated”

IIS 7.5 error: Handler “PageHandlerFactory-Integrated” has a bad module “ManagedPipelineHandler” in its module list

Today I installed Clean Windows Web Server 2008 R2 64-bit with IIS 7.5. To my surprise opening .NET 4.0 application I received the following error:

http-error-500.21-pagehandlerfactory-integrated


IIS 7.5 Detailed Error - 500.21 - Internal Server Error


Server Error in Application "DEFAULT WEB SITE"
Internet Information Services 7.5


[Error Summary]
HTTP Error 500.21 - Internal Server Error
Handler "PageHandlerFactory-Integrated" has a bad module "ManagedPipelineHandler" in its module list


[Detailed Error Information]
Module IIS Web Core
Notification ExecuteRequestHandler
Handler PageHandlerFactory-Integrated
Error Code 0x8007000d
Requested URL http://localhost:80/default.aspx
Physical Path C:\inetpub\wwwroot\default.aspx
Logon Method Anonymous
Logon User Anonymous


[Most likely causes:]
•Managed handler is used; however, ASP.NET is not installed or is not installed completely.
•There is a typographical error in the configuration for the handler module list.


[Things you can try:]
•Install ASP.NET if you are using managed handler.
•Ensure that the handler module's name is specified correctly. Module names are case-sensitive and use the format modules="StaticFileModule, DefaultDocumentModule, DirectoryListingModule".


[Links and More Information]
IIS core does not recognize the module.
View more information »

As it turns out, some glitch caused this problem, and somehow .NET was not registered with IIS.

Running the following commands solved this issue:

%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i
%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i

Javascript Popup Window to return value to Parent Window

Chào các bạn.
Khi lập trình, hay thiết kế web chúng ta có nhu cầu lấy dữ liệu từ một trang thứ 2 mà không muốn load lại trang chính. Chúng ta có thể dùng popup windows. Ví dụ như chọn một sản phẩm từ danh sách sản phẩm, chọn một nhân viên từ danh sách…. Tất nhiên cũng ta vẫn còn có nhiều cách khác nhau.

Javascript Popup Window to return value to parent window
Javascript Popup Window to return value to parent window

Hướng dẫn sau cho phép bạn tạo một trang popup và lấy dữ liệu đưa vào form của chúng ta. Đây chỉ là code HTML và Javascript, vậy nên bạn có thể áp dụng bất cứ chỗ nào bạn muốn (PHP, ASP.NET, MVC….).

Chúng ta cần 2 file. 1 file chứa form (parent) và 1 file chứa dữ liệu chúng ta muốn lấy (child).

Code trang parent.html

<body>
    <div class="container">
        <h3>Javascript Popup Window to return value to parent Window</h3>
        <table border="0" cellpadding="0" cellspacing="0">
            <tr>
                <td>
                    Họ tên:&nbsp;
                </td>

                <td>
                    <div class="input-group">
                        <input type="text" class="form-control" placeholder="Chọn nhân viên..." id="txtName">
                        <span class="input-group-btn">
                            <button class="btn btn-primary" type="button" onclick="SelectName()">Chọn...</button>
                        </span>
                    </div><!-- /input-group -->
                </td>
            </tr>
        </table>
        <br />
        <p>            
            <a href="http://tuanitpro.comjavascript-popup-window-to-return-value-to-parent-window">Hướng dẫn lấy dữ liệu từ Popup Javascript.</a>
        </p>
        <script type="text/javascript">
            var popup;
            function SelectName() {
                popup = window.open("/Home/Popup", "Popup", "width=400,height=300"); // Thay dường dẫn file bạn muốn mở
                popup.focus();
            }
        </script>
    </div>

Code file child.html

<body>
    <div>
        <h3>Danh sách nhân viên</h3>
        Click vào tên nhân viên để chọn
        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>#</th>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Username</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <th scope="row">1</th>
                    <td><a href="#" onclick="return SetName('Ngọc Trinh');">Ngọc Trinh</a></td>
                    <td>Otto</td>
                    <td>mdo</td>
                </tr>
                <tr>
                    <th scope="row">2</th>
                    <td><a href="#" onclick="return SetName('Phương Trinh');">Phương Trinh</a></td>
                    <td>Thornton</td>
                    <td>fat</td>
                </tr>
                <tr>
                    <th scope="row">3</th>
                    <td><a href="#" onclick="return SetName('Lệ Rơi');">Lệ Rơi</a></td>
                    <td>the Bird</td>
                    <td>twitter</td>
                </tr>
                <tr>
                    <th scope="row">4</th>
                    <td><a href="#" onclick="return SetName('Bà Tưng');">Bà Tưng</a></td>
                    <td>the Bird</td>
                    <td>twitter</td>
                </tr>
                <tr>
                    <th scope="row">5</th>
                    <td><a href="#" onclick="return SetName('Kenny Sang');">Kenny Sang</a></td>
                    <td>the Bird</td>
                    <td>twitter</td>
                </tr>
            </tbody>
        </table>
    </div>
    <script type="text/javascript">
        function SetName(value) {
            if (window.opener != null && !window.opener.closed) {
                var txtName = window.opener.document.getElementById("txtName"); // ID này là của parent form
                txtName.value = value;
            }
            window.close();
        }
    </script>
</body>

Chúc các bạn thành công.

HTML là gì?

1. HTML là gì?

HTML (tiếng Anh, viết tắt cho HyperText Markup Language, tức là “Ngôn ngữ Đánh dấu Siêu văn bản”) là một ngôn ngữ đánh dấu được thiết kế ra để tạo nên các trang web, nghĩa là các mẩu thông tin được trình bày trên World Wide Web. Được định nghĩa như là một ứng dụng đơn giản của SGML, vốn được sử dụng trong các tổ chức cần đến các yêu cầu xuất bản phức tạp, HTML giờ đây đã trở thành một chuẩn Internet do tổ chức World Wide Web Consortium (W3C) duy trì. Phiên bản mới nhất của nó hiện là HTML 5, với rất nhiều cải tiến. Có thể tương lai của web.

HTML nói chung tồn tại như là các tập tin văn bản chứa trên các máy tính nối vào mạng Internet. Các file này có chứa thẻ đánh dấu, nghĩa là, các chỉ thị cho chương trình về cách hiển thị hay xử lý văn bản ở dạng văn bản thuần túy. Các file này thường được truyền đi trên mạng internet thông qua giao thức mạng HTTP, và sau đó thì phần HTML của chúng sẽ được hiển thị thông qua một trình duyệt web, một loại phần mềm trực quan đảm nhiệm công việc đọc văn bản của trang cho người sử dụng), phần mềm đọc email , hay một thiết bị không dây như một chiếc điện thoại di động.

Ðể viết HTML cho trang Web, bạn hãy start chương trình NotePad của Microsoft có đi kèm theo với Windows. Ðó là một ASCII Editor. Viết xong, bạn hãy save nó vào một folder nào đó dễ nhớ. Tên của file này bắt buộc phải có tận cùng là .htm hoặc .html Ví dụ: file.htm. Ðể thưởng thức thành quả của mình, bạn hãy open file đó bằng một Browser.

2. Cấu trúc cơ bản:

Một document HTML luôn bắt đầu bằng <html> và kết thúc bằng </html> (trong đó bạn cũng có thể viết nhỏ hoặc viết hoa <html> và </html>). Nhờ có cặp TAG này mà Browser biắt được đó là HTML – document để trình duyệt. Những chữ đó chỉ để dành riêng cho Browser, người đọc chỉ nhận được những gì viết giữa cặp TAG <body> và </body>. Trong một document html, chú thích được dùng như sau:

<!-- Ðây là dòng chú thích, chỉ dành riêng cho bạn, browser bỏ qua dòng này -->

Cấu trúc chuẩn của một tài liệu HTML như sau:

<html>
   <head>
     <title>Tiêu đề của trang web</title>
   </head>
   <body>
           Phần bạn cần trình bày nội dung
   </body>
</html>

Trong “head” ta còn có thể đưa rất nhiều thông tin vào cho browser, search engine… Cái đó sẽ được đề cập đến trong một mục riêng.

3. Các thẻ cơ bản trong HTML:

Một tài liệu HTML được tạo nên từ các cặp thẻ html

  • Thẻ HTML được bắt đầu bằng dấu < (dấu nhỏ hơn) và kết thúc bằng dấu > (dấu lớn hơn)
  • Nội dung nằm giữa dấu <> là tên thẻ. Ví dụ <b>, ta đọc là thẻ b
  • Cặp thẻ HTML được tạo nên từ thẻ mở và thẻ đóng
  • Các tag đầu tiên trong một cặp là thẻ bắt đầu, các thẻ thứ hai là thẻ kết thúc
  • Thẻ Bắt đầu và thẻ kết thúc còn được gọi là thẻ mởthẻ đóng
  • Thẻ đóng kết thúc bằng dấu / (</tenthe>)
  • Nội dung của thẻ sẽ được nằm giữa thẻ đóng và thẻ mở
  • Một số thẻ chỉ có thẻ mở mà không có thẻ đóng (như các thẻ <img>, <br />,  <hr />)

Ví dụ:  Về cặp thẻ: <b>Nội dung thẻ</b>

Các thẻ thường sử dụng trong HTML

3.1. Các thẻ tiêu đề (HTML Headings):

  • Bao gồm các thẻ từ <h1> đến <h6>: thường được sử dụng để thể hiện cho tiêu đề bài viết, bản tin, các mục nhấn mạnh . . .
  • Font chữ (size) của nội dung trong các thẻ giảm từ <h1> đến <h6> (h1 lớn nhất, h6 nhỏ nhất).

Khi xuất ra ngoài thì các bạn sẽ thấy như sau:

  • Nội dung thẻ h1

  • Nội dung thẻ h2

  • Nội dung thẻ h3

  • Nội dung thẻ h4

  • Nội dung thẻ h5
  • Nội dung thẻ h6

3.2. Đoạn văn bản trong HTML (HTML Paragraphs):

Đoạn văn bản trong tài liệu HTML được định nghĩa bằng thẻ <p>

 3.3. Liên kết (HTML Links):

  • Một trang website bao gồm rất nhiều trang web (web page), các web page liên kết lại với nhau để tạo lên website.
  • Liên kết trong HTML được định nghĩa bằng cặp thẻ <a>

Các thuộc tính (Attribute) của thẻ <a>

  • href: quy định địa chỉ (url) mà liên kết trỏ tới
  • target: (đích) thuộc tính này sẽ quy định liên kết sẽ được mở ra ở đâu: _self (trang hiện tại), _blank (cửa sổ mới), . .

3.4. HTML Line Breaks <br/>:

Sử dụng <br /> để xuống dòng trong một đoạn văn bản

Tuy nhiên chúng ta không nên sử dụng thẻ <br /> trong tài liệu HTML (khuyến cáo)

3.5. HTML Lines (<hr />):

Thẻ <hr /> sẽ tạo một đường kẻ ngang trong trang HTML. <hr /> là thẻ đơn không có thẻ đóng

<hr/>

 3.6. HTML images (Hình ảnh):

Để chèn hình ảnh vào tài liệu HTML ta sử dụng thẻ <img>, đây là thẻ HTML không có thẻ đóng

Các thuộc tính của thẻ <img>

  • src=”images.jpg”: Chỉ ra đường dẫn tập tin hình ảnh (có thể là đường dẫn tuyệt đối hoặc tương đối, vấn đề này mình sẽ giải thích ở một topic khác)
  • alt=”Mô tả ”:  Nội dung sẽ được hiển thị khi đường dẫn tới tập tin hình ảnh không tồn tại
  • title=”Tiêu đề”: Nội dung hiển thị khi đưa trỏ chuột lên hình.
  • width, height: Độ rộng và độ cao của file hình được tính bằng px, nếu không có thuộc tính width, height thì mặc định sẽ lấy kích thước gốc của file hình

3.7. Các thẻ định dạng text (HTML Text Formatting):
<b> (bold): Chữ In đậm

<u> (Underline): Chữ gạch chân

<i> (italic): Chữ in nghiên

<big> (Big): Chữ lớn hơn

<em>(emphasized): Chữ in nghiêng, Nhấn mạnh hơn <i>

 Tổng kết: Bài viết này là những kiến thức cơ bản về HTML và cấu tạo cũng như các thẻ hổ trợ trong HTML. Hy vọng bài viết này sẽ là tài liệu bổ ích cho những bạn mới đầu làm quen với thiết kế website. Ở những bài viết sau chúng ta sẽ cũng tìm hiểu các vấn để khác nhằm để xây dựng một giao diện website hoàn chỉnh.

Multiple file upload in ASP.NET MVC

Khi lập trình web với ASP.NET MVC hay bất kỳ ngôn ngữ nào khác như PHP chẳng hạn, chúng ta đều gặp những tình huống liên quan đến Upload file lên hosting, dễ thấy nhất là upload hình sản phẩm cho một sản phẩm nào đó.

Với ASP.NET MVC chúng ta dễ dàng làm được điều đó, bạn có thể upload 1 file hoặc upload nhiều file (Multiple file upload) trong ASP.NET MVC cùng lúc. Nó cực kỳ hữu ích trong nhiều trường hợp. Đoạn code nhỏ sau đây sẽ minh họa cho vấn đề này.

Multiple file upload in ASP.NET MVC
Multiple file upload in ASP.NET MVC

Code HTML

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Upload file trong ASP.NET MVC</title>
    <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            var max_fields = 10; //maximum input boxes allowed
            var wrapper = $(".myinput"); //Fields wrapper
            var add_button = $(".btnAddNew"); //Add button ID

            var x = 0; //initlal text box count
            $(add_button).click(function (e) { //on add input button click
                e.preventDefault();
                if (x < max_fields) { //max input box allowed
                    x++; //text box increment
                    $(wrapper).append('<div>   <input type="file" name="uploadFile['+x+']" /><a href="#" class="btnRemove">Xóa</a></div>'); //add input box
                }
            });

            $(wrapper).on("click", ".btnRemove", function (e) { //user click on remove text
                e.preventDefault(); $(this).parent('div').remove(); x--;
            })
        });
    </script>
</head>
<body>
    <div>
        <h2>Upload file trong ASP.NET MVC</h2>
        <div style="color:red">
            @Html.Raw(TempData["Msg"])
        </div>
        <fieldset>
            <legend>Upload file</legend>
            @using (Html.BeginForm("Upload", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
            {

                <label>Chọn file: </label>
                <br />
                <input type="file" name="uploadFile" required /><br />

                <input type="submit" value="Upload" />

            }
        </fieldset>
        <hr />
        <h3>Upload nhiều file trong ASP.NET MVC</h3>
        <fieldset>
            <legend>Upload multi file</legend>
            @using (Html.BeginForm("UploadMulti", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
            {

                <label>Chọn file: </label><br />
                <a class="btnAddNew" href="#">Thêm</a>
                <br />
                <div id="myinput" class="myinput">
                    <input type="file" name="uploadFile[0]" required /><br />
                </div>
                <br />
                <input type="submit" value="Upload" />

            }
        </fieldset>
        
Chia sẻ kiến thức Lập trình .NET
</div> </body> </html>

Code cs

/**   FileName: UploadController.cs 
          Project Name: DateTime Ajax
          Date Created: 12/17/2014 11:30:58 PM 
          Description:  File Upload trong ASP.NET MVC
          Version: 0.0.0.0 
          Author: Lê Thanh Tuấn - Khoa CNTT
          Author Email: [email protected] 
          Author Mobile: 0976060432
          Author URI: http://tuanitpro.com 
          License: 
     */

    public class UploadController : Controller
    {
        // GET: Upload
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Upload(HttpPostedFileBase uploadFile)
        {
            if (ModelState.IsValid)
            {
                string filePath = Path.Combine(HttpContext.Server.MapPath("/Uploads/demo"),
                                               Path.GetFileName(uploadFile.FileName));
                uploadFile.SaveAs(filePath);
                TempData["Msg"] = string.Format("Upload file {0} thành công", uploadFile.FileName);
            }
            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult UploadMulti(List<HttpPostedFileBase> uploadFile)
        {
            string abc = "";
            string def = "";
            foreach (var item in uploadFile)
            {

                string filePath = Path.Combine(HttpContext.Server.MapPath("/Uploads/demo"),
                                               Path.GetFileName(item.FileName));
                item.SaveAs(filePath);

                abc = string.Format("Upload {0} file thành công", uploadFile.Count);

                def += item.FileName + "; ";


            }
            TempData["Msg"] = abc + "</br>" + def;
            return RedirectToAction("Index");
        }
    }

Live demo

Chúc các bạn thành công.

Vừa gà vừa chó, bó lại cho tròn, ba mươi sáu con, một trăm chân chẵn. Hỏi mấy gà, mấy chó?

Vừa gà vừa chó, bó lại cho tròn, ba mươi sáu con, một trăm chân chẵn. Hỏi mấy gà, mấy chó?
Vừa gà vừa chó, bó lại cho tròn, ba mươi sáu con, một trăm chân chẵn. Hỏi mấy gà, mấy chó?

Có một bài toán dân gian khá thú vị như sau:

Vừa gà vừa chó
Bó lại cho tròn
Ba mươi sáu(36) con
Một trăm(100) chân chẵn
Hỏi mấy gà, mấy chó?

Đây là bài toán vui, từ khi học tiểu học mình đã biết, lên trung học, học giải phương trình cũng gặp lại nó. Và bây giờ, làm lập trình, tự dưng nhớ tới nó, nên viết ra đây, coi như chia sẻ cho các bạn mới học lập trình có thêm hào hứng, giải quyết các bài tập nho nhỏ, vui vẻ tương tự.

Cách giải nó như sau:

Gọi x là số gà
Số chó là: 36 – x
Số chân gà: 2x
Số chân chó: 4(36-x)
theo đề bài ta có:
2x + 4(36 – x) =100
2x + 144 – 4x = 100
2x = 144 – 100
2x = 44
x = 22
Vậy số gà là 22 con
Số chó : 36 – 22 = 14

Bạn bảo mấy con chó đặt 2 chân trước lên ghế,tổng số chân dưới đất sẽ là 36 x 2  = 72 chân. Suy ra số chân trên ghế là 28 chân.
Vậy có 14 con chó ….

Dùng hệ phương trình
Gọi x là gà, y là chó
Ta có hệ pt:
x + y = 36
2x + 4y = 100
Giải hệ pt
x = 22,y = 14
Vậy gà có 22 con, chó có 14 con. Mời các bạn chia sẻ thêm cách giải hay, thú vị khác nữa nhé.

Vậy thì làm sao để giải nó bằng cách lập trình. Đây không phải vấn đề khó với nhiều bạn, tuy nhiên mình thấy vui vẻ, nên vẫn viết ra đây.

Sau đây là cách giải trong một số ngôn ngữ lập trình như Pascal, C++, C#, Java, PHP, ASP.NET, Javascript. Trường hợp máy bạn không cài sẵn IDE, bạn có thể sử dụng trang web http://ideone.com để chạy thử code.

Vì số con là 36 và số chân là 100. Giả sử tất cả là chó, thì số con tối đa là 100/4 = 25 (con). Tối thiểu là 36 / 4 = 9 (con). Như vậy chúng ta chỉ cần sử dụng vòng lặp for từ 9->25. Tối ưu hơn so với từ 0 -> 36

Pascal

program HelloWorld;
var i :Integer;
begin
  	writeln('Giai bai toan dan gian bang Pascal');
	writeln('Vua ga vua cho');
	writeln('Bo lai cho tron');
	writeln('Ba muoi sau(36) con');
	writeln('Mot tram(100) chan chan');
	writeln('Hoi may ga, may cho?');
	for i:= 9 to 25 do
		if((i * 2 + (36 - i) * 4) = 100) then
			writeln('So ga la: ', i);
			writeln('So cho la: ', 36 - i);
	
end.

C++

#include <string>
#include<iostream>;
#include<stdio.h>;
 
using namespace std;

int main(){
	cout << "Gia bai toan dan gian trong C++\n";
	cout << "Vua ga vua cho\n";
	cout << "Bo lai cho tron\n";
	cout << "Ba muoi sau(36) con\n";
	cout << "Mot tram(100) chan chan\n";
	cout << "Hoi may ga, may cho?\n";
	cout << "\n";
	for (int i = 9; i < 25; i++)
	{
		if ((i * 2 + (36 - i) * 4) == 100){
			cout << "So ga la: " << i << "\n";
			cout << "So cho la: " << (36 - i) << "\n";
                        break;
		}
	}
}

Java

public class Main {

	public Main() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("Giải bài toán dân gian trong Java");
		System.out.println("Vừa gà vừa chó");
		System.out.println("Bó lại cho tròn");
		System.out.println("Ba mươi sáu(36) con");
		System.out.println("Một trăm(100) chân chẵn");
		System.out.println("Hỏi mấy gà, mấy chó?\n");
		for(int i = 9; i < 25; i++){
			if((i*2+(36-i)*4)==100){
				System.out.println("Số gà là: " + i);
				System.out.println("Số chó là: " + i);
			}
		}
	}
}

C#

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Gia bai toan dan gian trong C#");
            Console.Write("Vua ga vua cho\n");
            Console.Write("Bo lai cho tron\n");
            Console.Write("Ba muoi sau(36) con\n");
            Console.Write("Mot tram(100) chan chan\n");
            Console.WriteLine("Hoi may ga, may cho?\n");
            for (int i = 9; i <= 25; i++)
            {
                if ((2 * i + (36 - i) * 4) == 100)
                {
                    Console.WriteLine("So ga la: " + i);
                    Console.WriteLine("So cho la: " + (36 - i));
                    break;
                }
            }

            Console.ReadKey();
        }
    }

ASP.NET

void GiaiBaiToanDanGian()
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 9; i < 25; i++)
        {
            if ((i * 2 + (36 - i) * 4) == 100)
            {
                sb.AppendLine("Số gà là: " + i);
                sb.AppendLine("Số chó là: " + (36 - i));
            }
        }
        Label1.Text = sb.ToString();
    }

PHP

<html>
	<head>
		<meta charset="UTF-8"/>
		<title>Bài toán dân gian</title>				
	</head>
	<body>
		<b>Giải bài toán dân gian trong PHP</b></br>
		Vừa gà vừa chó </br>
		Bó lại cho tròn </br>
		Ba mươi sáu(36) con </br>
		Một trăm(100) chân chẵn</br>
		Hỏi mấy gà, mấy chó?</br>
		</br>
		<?php 
			for($i = 9; $i < 25; $i ++)
			{
				if(($i * 2 + (36-$i)*4) == 100)
				{
					echo 'Số gà là: '.$i.'</br>';
					echo 'Số chó là: '.(36 - $i);
				}
			}
		?>
	</body>
</html>

Javascript

<script type="text/javascript">
	alert('Giai bai toan dan gian');
	for(i = 9; i < 25; i++)
	{
		if((i * 2 + (36-i)*4) === 100){
			alert('Số gà là: ' + i + '; Số chó là: '+(36-i));
		}
	}
</script>

Chúc các bạn học lập trình vui vẻ

Convert DataTable to List trong C#

Khi làm việc với .NET, thì MS đã cung cấp cho chúng ta đối tượng DataTable. Tuy nhiên trong nhiều trường hợp, DataTable tỏ ra không linh hoạt và tiện dụng như List. Do đó chúng ta rất có nhu cầu chuyển đổi từ DataTable sang List để tiện sử dụng.

Convert Datatable to List
Convert Datatable to List

Class này cung cấp cho các bạn 2 phương thức để chuyển đổi từ DataTable sang List và ngược lại.

/* 
FileName: ConvertListToDataTable.cs
Project Name: ColorLife
Date Created: 11/30/2014 8:44:44 AM
Description: Convert Between List and DataTable
Version: 1.0.0.0
Author:	Lê Thanh Tuấn
Author Email: [email protected]
Author Mobile: 0976060432
Author URI: http://tuanitpro.com
License: 

*/

using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;

public static class ConvertListToDataTable
{
	
	// List<Student> students = Data.GetStudents();	
	// Converts List To DataTable
	// DataTable studentTbl = students.ToDataTable(); 

	public static DataTable ListToDataTable<T>(this IList<T> data)
	{
		DataTable dataTable = new DataTable(typeof(T).Name);
		PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
		foreach (PropertyInfo prop in props)
		{
			dataTable.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
		}
		foreach (T item in data)
		{
			var values = new object[props.Length];
			for (int i = 0; i < props.Length; i++)
			{
				values[i] = props[i].GetValue(item, null);
			}
			dataTable.Rows.Add(values);
		}
		return dataTable;
	}

	//  Converts DataTable To List
	//  DataTable dtTable = GetEmployeeDataTable();
	//  List<Employee> employeeList = dtTable.DataTableToList<Employee>();
	
	public static List<T> DataTableToList<T>(this DataTable table) where T : class, new()
	{
		try
		{
			List<T> list = new List<T>();

			foreach (var row in table.AsEnumerable())
			{
				T obj = new T();

				foreach (var prop in obj.GetType().GetProperties())
				{
					try
					{
						PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
						propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
					}
					catch
					{
						continue;
					}
				}

				list.Add(obj);
			}

			return list;
		}
		catch
		{
			return null;
		}
	}	
}

Lưu ý: Có thể code không chạy trong một vài trường hợp như dữ liệu kết hợp phức tạp. Tên cột trong DataTable khác với thuộc tính trong List.

Chúc các bạn thành công.

Ajax là gì?

AJAX, viết tắt từ Asynchronous JavaScript and XML (JavaScript và XML không đồng bộ), là bộ công cụ cho phép tăng tốc độ ứng dụng web bằng cách cắt nhỏ dữ liệu và chỉ hiển thị những gì cần thiết, thay vì tải đi tải lại toàn bộ trang web. AJAX không phải một công nghệ đơn lẻ mà là sự kết hợp một nhóm công nghệ với nhau. Trong đó, HTML và CSS đóng vai hiển thị dữ liệu, mô hình DOM trình bày thông tin động, đối tượng XMLHttpRequest trao đổi dữ liệu không đồng bộ với máy chủ web, còn XML là định dạng chủ yếu cho dữ liệu truyền. Đây đều là công nghệ sẵn có nhưng Javacript đã lắp ráp chúng lại để thực hiện những “sứ mệnh” đáng khâm phục.

Từ Ajax được ông Jesse James Garrett đưa ra và dùng lần đầu tiên vào tháng 2 nãm 2005 để chỉ kỹ thuật này, mặc dù các hỗ trợ cho Ajax đã có trên các chương trình duyệt từ 10 năm trước. Ajax là một kỹ thuật phát triển web có tính tương tác cao bằng cách kết hợp các ngôn ngữ:

  • HTML (hoặc XHTML) với CSS trong việc hiển thị thông tin
  • Mô hình DOM (Document Object Model), được thực hiện thông qua JavaScript, nhằm hiển thị thông tin động và tương tác với những thông tin được hiển thị
  • Đối tượng XMLHttpRequest để trao đổi dữ liệu một cách không đồng bộ với máy chủ web.
  • XML thường là định dạng cho dữ liệu truyền, mặc dầu bất cứ định dạng nào cũng có thể dùng, bao gồm HTML định dạng trước, văn bản thuần (plain text), JSON và ngay cả EBML.

AJAX hoạt động như thế nào?

Ứng dụng web truyền thống (trái) và ứng dụng AJAX.
Ứng dụng web truyền thống (trái) và ứng dụng AJAX.

Theo mô hình hoạt động bình thường, client sẽ gửi một HTTP Request lên Server, sau đó Server thực hiện một số khâu xử lý như lấy lại dữ liệu, tính toán, kiểm tra sự hợp lệ của thông tin, sửa đổi bộ nhớ, sau đó gửi lại một trang HTML hoàn chỉnh tới máy khách. Về mặt kỹ thuật, phương pháp này nghe có vẻ hợp lý nhưng cũng khá bất tiện và mất thời gian, bởi khi server đang thực hiện vai trò của nó thì người dùng sẽ làm gì? Có vấn đề gì ở đây? Mỗi lần như vậy Client sẽ gửi toàn bộ nội dung website lên Server, và Server cũng trả về tương ứng. Bạn hình dung, khi xem một bài báo, hay website chia sẻ hình ảnh, bạn chỉ quan tâm nội dung bài báo, hình ảnh đó mà thôi, không cần tải hết cả trang làm gì đó. Đó là hạn chế, bạn sẽ phải tốn thời gian chờ đợi thứ không mong muốn. Không ai muốn chờ đợi cả.

Để khắc phục hạn chế trên, các chuyên gia phát triển giới thiệu hình thức trung gian – cơ chế xử lý AJAX – giữa máy khách và máy chủ. Điều này giống như việc tăng thêm một lớp giữa cho ứng dụng để giảm quá trình “đi lại” của thông tin và giảm thời gian phản ứng. Thay vì tải lại (refresh) toàn bộ một trang, nó chỉ nạp những thông tin được thay đổi, còn giữ nguyên các phần khác, thời gian chờ có thể thay bằng thông điệp ‘loading…’, ‘đang tải dữ liệu…’… Vì thế, khi duyệt một trang hỗ trợ AJAX, người sử dụng không bao giờ nhìn thấy một cửa sổ trắng (blank) và biểu tượng đồng hồ cát – dấu hiệu cho thấy máy chủ đang thực hiện nhiệm vụ. Ví dụ, trong một website ảnh, với ứng dụng truyền thống, toàn bộ trang chứa các ảnh sẽ phải mở lại từ đầu nếu có một thay đổi nào đó trên trang. Còn khi áp dụng AJAX, DHTML chỉ thay thế đoạn tiêu đề và phần vừa chỉnh sửa, do vậy tạo nên các giao dịch trơn tru, nhanh chóng.

Tương tác đồng bộ trong ứng dụng web truyền thống (trên) và dị bộ trong ứng dụng AJAX. (
Tương tác đồng bộ trong ứng dụng web truyền thống (trên) và bất đồng bộ trong ứng dụng AJAX.

Các ứng dụng AJAX

Hiện nay thì khá nhiều website đã và đang ứng dụng ajax. Đơn giản thì chúng ta hay đăng ký thành viên trên các diễn đàn, website. Ngay sau khi chúng ta nhập xong username hay email, hệ thống đã phản hồi cho chúng ta biết tài khoản đó tồn tại hay chưa, mà không cần nhấn nút Submit như truyền thống. Đó là một trong vô số các ứng dụng của AJAX.

Ưu điểm và hạn chế

Cũng như bất kỳ công nghệ khác, AJAX có thể bị sử dụng quá nhiều trong một website, vì họ chỉ thấy những ưu điểm mà AJAX mang lại chớ không quan tâm đến những khuyết điểm của AJAX, để tranh tình trang trên, có thể liệt kê một số đặc điểm của AJAX như sau:

– Ưu điểm

  • Nó giúp việc thiết kế web đa dạng hơn và tăng tính tương tác của website với người dùng.
  • Nó sử dụng các công nghệ đã có sẵn nên dễ học và sử dụng
  • Nhờ tính phổ biến của nó, đã khuyến khích việc phát triển các khuôn mẫu mà sẽ giúp lập trình viên tránh khỏi các vết xe đổ trước.
  • Được hỗ trợ trong các trình duyệt phổ biến hiện nay.
– Hạn chế
  • Bạn không thể bookmark nó vào favourite trên trinh duyệt hay gởi link đến cho bạn bè, vì tất cả quá trình nó thực hiện ngầm và không hiển thị trên address.
  • Không thể hiện thị nội dung trên các trang tìm kiếm vì các trang tìm kiếm hiện nay vẫn chưa hỗ trợ tìm vì rất khó tìm và gần như không thể tìm đc.
  • Không thể sử dụng nút back vì back cũng là chính nó.
  • Với một số trình duyệt, do nhu cầu bảo mật, sẽ tắt chức năng thực hiện javascript nên ajax không thể chạy, hay trong một vài host, không hỗ trợ vào sâu cấu hình server nên hay bị lỗi “Access denied”

Nhưng với những điểm hạn chế nói trên thì AJAX vẫn đang được các lập trình viên sử dụng rộng rãi và đang nghiên cứu để cải thiện nó, ví dụ như vừa update thông tin trên web, vừa thay đổi trên thanh address để có thể sử dụng một số chức năng liên quan tới địa chỉ tuyệt đối này.

Kết: sử dụng ajax là cả một nghệ thuật.

Ví dụ về việc sử dụng Ajax đơn giản

(Note: Ở đây thực hiện trong ASP.NET, bạn hoàn toàn có thể thực hiện trên ngôn ngữ khác được)
Ví dụ sau đây chúng ta thực hiện việc lấy giờ trên Server. Thông qua AJAX sẽ cho chúng ta biết thời gian của Server mà không cần tải lại toàn bộ trang web. Chỉ lấy những gì chúng ta cần mà thôi.
Chúng ta sẽ có 3 file. ajax.js, Default.aspx, Ajax.aspx (Có thể khác với ngôn ngữ khác. defaul.php, ajax.php….)
Đầu tiên chúng ta tạo 1 file ajax.js (File javascript này đảm nhiệm việc gọi XMLHttpRequest để trao đổi dữ liệu)
Code
File ajax.js

/** FileName: ajaxcore.js
Project Name: Ajax
Date Created: 30/10/2014 10:28:58 PM
Description: File Ajax core, thuần JavaScript, dùng để gọi Server xử lý
Version: 0.0.0.0
Author:	Lê Thanh Tuấn - Khoa CNTT
Author Email: [email protected]
Author Mobile: 0976060432
Author URI: http://tuanitpro.com

License: 
*/
var xmlHttp = null;

function loadXmlHttp() {
    if (window.XMLHttpRequest) { // IE7, Mozilla, Safari, Opera
        xmlHttp = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        try {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); //IE 5.x, 6
        } catch (e) {}
    }
}

function sendRequest(url) {
    loadXmlHttp();
    if (xmlHttp) {
        xmlHttp.open("GET", url, true); // true = async
        xmlHttp.onreadystatechange = onCallback;
        xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xmlHttp.send(null);
    }
}

function onCallback() {
    if (xmlHttp.readyState == 4) {
        if (xmlHttp.status == 200) {
            var r = document.getElementById('results');
            r.innerHTML = xmlHttp.responseText;
        } else {
            alert('Error: ' + xmlHttp.status);
        }
    }
}

function loading() {
    document.getElementById("results").innerHTML = 'Đợi em tí...';
}

function getContent(url) {
    loading();
    sendRequest(url);
}

Cách dùng:

Trang default.aspx Ajax Demo

1. Trên trang HTML tạo một div.
Nơi chứa dữ liệu
2. gọi hàm getContent('URL'); VD: Load Content

Ajax Demo

DateTime: Ajax DateTime:
Vùng chứa dữ liệu, sẽ bị thay thế
http://tuanitpro.com

Trang default.aspx.cs

/** FileName: Default.aspx.cs
Project Name: DateTime Ajax
Date Created: 30/10/2014 10:28:58 PM
Description: Default.aspx, hiển thị dữ liệu
Version: 0.0.0.0
Author:	Lê Thanh Tuấn - Khoa CNTT
Author Email: [email protected]
Author Mobile: 0976060432
Author URI: http://tuanitpro.com
License: 
*/
using System;

public partial class Ajax_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            lblDatTime.Text = DateTime.Now.ToString();
        }
    }
}

Trang Ajax.aspx.cs. Không quan tâm phần giao diện HTML.

/** FileName: Ajax.aspx.cs
Project Name: DateTime Ajax
Date Created: 30/10/2014 10:28:58 PM
Description: Ajax.aspx, trả về kết quả hiển thị lên website
Version: 0.0.0.0
Author:	Lê Thanh Tuấn - Khoa CNTT
Author Email: [email protected]
Author Mobile: 0976060432
Author URI: http://tuanitpro.com
License: 
*/
using System;

public partial class Ajax_Ajax : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write(DateTime.Now.ToString());
    }
}

Demo kết quả:

ajax-datetime
Demo Ajax DateTime

[ASP.NET] Hướng dẫn chèn logo vào hình ảnh

Chèn logo vào hình ảnh ASP.NET
Chèn logo vào hình ảnh ASP.NET

Trong bài viết Hướng dẫn chèn chữ vào hình ảnh thì chúng ta đã biết cách làm thế nào để đánh dấu bản quyền cho hình ảnh trên website của mình. Khá là thú vị, tuy nhiên chúng ta có quyền đặt câu hỏi rằng, tại sao không chèn Logo của mình vào bức ảnh đó. ASP.NET có làm được không? Nếu có, thì làm thế nào để chèn Logo vào hình ảnh?

Tất nhiên là ASP.NET có hỗ trợ và chúng ta hoàn toàn làm được điều đó, không hề khó khăn gì cả.
Đầu tiên chúng ta sẽ tạo ra một trang LogoOnImage.aspx. Trong trang LogoOnImage.aspx.cs chúng ta sẽ thêm vào 2 thư viên sau:
<prelang=”csharp”> using System.Drawing; using System.Drawing.Imaging;

Trong sự kiện Page_Load chúng ta sẽ viết code cho nó như sau:

protected void Page_Load(object sender, EventArgs e)
    {
        // Đường dẫn file ảnh. 
        string imageFile = Server.MapPath("~/images/fruit.jpg");
        // Đường dẫn file Logo cần chèn
        string logo = Server.MapPath("~/images/logo.png");

        // Tạo đối tượng Bitmap truyền vào đường dẫn File ảnh
        Bitmap myBitmap = new Bitmap(imageFile);
        // Tạo đối tượng Graphic từ Bitmap
        Graphics myGraphics = Graphics.FromImage(myBitmap);
       
        // Vẽ lại hình ảnh, chèn nội dung mới vào.
        Bitmap myBitmapLogo = new Bitmap(logo);
       
        myGraphics.DrawImage(myBitmapLogo, new Point(550, 400));

        // Xuất hình ảnh mới
        Response.ContentType = "image/jpeg";
        myBitmap.Save(Response.OutputStream, ImageFormat.Jpeg);

        // Dùng code này nếu lưu ảnh vào ổ cứng của bạn.
        // myBitmap.Save(Server.MapPath("~/images/aodai.jpg"));
    }

Thât đơn giản và thú vị. Chúc các bạn thành công.

[ASP.NET] Hướng dẫn chèn chữ vào hình ảnh

Write Text On Image in ASP.NET
Nguồn: flickr.com – Ton Ten

Khi bạn sở hữu một website, bạn chia sẻ hình ảnh lên đó, và lý do nào đó bạn không muốn người khác sử dụng lại. Ví dụ như đó là hình ảnh ngôi sao nổi tiếng mà bạn chụp được. Ảnh sản phẩm bạn đang kinh doanh, không thể cho đối thủ cạnh tranh lấy và sử dụng trên website của họ, hoặc đơn giản là bạn muốn đánh dấu bản quyền lên hình ảnh của mình. Bạn có lý do chính đáng để làm như vậy, và bạn sẽ đánh dấu lên bức ảnh (watermark) của mình. Điều này chúng ta hay gặp khi lướt web, bạn cứ thử vào một trang web bất kỳ, sẽ thấy họ ghi chú lên ảnh logo hay tên website….
Có nhiều công cụ khác nhau giúp bạn làm điều đó, bạn có thể dùng công cụ online như https://www.watermark.ws, hoặc photoshop, mình thì hay dùng phần mềm FastStone Photo Resizer để chèn chữ (chèn logo) lên ảnh. Và còn rất nhiều công cụ khác…
Tuy vậy ở khía cạnh là một lập trình viên, bạn có thể không muốn dùng chúng, vì nó không chủ động. Bạn muốn tạo ra một công cụ hay chức năng hay ho nào đó, hình ảnh đưa lên website của bạn sẽ tự động chèn watermark vào. Thật thú vị phải không nào? Nếu bạn đang lập trình web với ASP.NET thì thật đơn giản để làm điều đó. Chúng ta sẽ sử dụng các thư viện .NET cung cấp sẵn và bắt tay vào ngay thôi. Hướng dẫn sau sẽ giúp bạn chèn chữ lên ảnh trong ASP.NET.

Đầu tiên chúng ta tạo ra một trang TextOnImage.aspx. Trong sự kiện Page_Load chúng ta sẽ viết code cho nó như sau:

Chú ý: Ta cần 2 thư viên sau – hãy thêm chúng vào.

using System.Drawing;
using System.Drawing.Imaging;

Code

 
protected void Page_Load(object sender, EventArgs e)
    {
        // Đường dẫn file ảnh. 
        string imageFile = Server.MapPath("~/images/girlvn.jpg");
        string textToWrite = "AO DAI VIET NAM";

        // Tạo đối tượng Bitmap truyền vào đường dẫn File ảnh
        Bitmap myBitmap = new Bitmap(imageFile);
        // Tạo đối tượng Graphic từ Bitmap
        Graphics myGraphics = Graphics.FromImage(myBitmap);
        // Định dạng Style
        StringFormat myStringFormat = new StringFormat();
        myStringFormat.Alignment = StringAlignment.Near;

        myGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        Font myFont = new Font("Tahoma", 35, FontStyle.Regular);
        Color fontColor = Color.White;
        SolidBrush myBrush = new SolidBrush(fontColor);

        // Vẽ lại hình ảnh, chèn nội dung mới vào.
        myGraphics.DrawString(textToWrite, myFont, myBrush, new Point(430, 410), myStringFormat);

        // Xuất hình ảnh mới
        Response.ContentType = "image/jpeg";
        myBitmap.Save(Response.OutputStream, ImageFormat.Jpeg);

        // Dùng code này nếu lưu ảnh vào ổ cứng của bạn.
        // myBitmap.Save(Server.MapPath("~/images/aodai.jpg"));
    }

OK. Chúng ta F5 để xem kết quả. Nếu hiện ra như hình ở đầu bài viết thì chúc mừng bạn đã thành công.
Để sử dụng ở trang khác, ở đây chúng ta tạo thêm một trang Default.aspx.
Thêm code này vào và xem kết quả nhé.


Tuyệt vời. Tuy nhiên không dừng lại ở đó, chúng ta muốn nó phải chèn chữ vào hình cho chúng ta chọn, chứ không phải gán cứng như trên.
Chúng ta sửa lại một chút hàm Page_Load như sau: Chỉ cần sửa 2 dòng dưới này thôi nhé

 
string imageFile =Server.MapPath( Request.QueryString["file"]);
string textToWrite = Request.QueryString["text"];

Trên trang Default.aspx thay bằng. Từ nay về sau bạn chỉ cần dùng đường dẫn này thì mọi hình ảnh trên website của bạn sẽ được chèn nội dung vào. Thật đơn giản phải không nào?


Kết quả

Write Text On Image in ASP.NET
Nguồn: flickr.com – Ton Ten

Chúc các bạn thành công.

Categories and Subcategories

The adjacency model

The fundamental structure of the adjacency model is a one-to-many relationship between a parent entry and its child entries. As with any one-to-many relationship, the child entries carry a foreign key to their parent. What makes the adjacency model different is that the parent and child entries are both stored in the same table.

create table categories
( id       integer     not null  primary key 
, name     varchar(37) not null
, parentid integer     null
, foreign key parentid_fk (parentid) 
      references categories (id)
);

Here’s some sample data that might populate this table, and we should be able to get an idea of the parent-child relationships (if not grasp the entire hierarchy) just by looking at the data:

id name parentid
1 animal NULL
2 vegetable NULL
3 mineral NULL
4 doggie 1
5 kittie 1
6 horsie 1
7 gerbil 1
8 birdie 1
9 carrot 2
10 tomato 2
11 potato 2
12 celery 2
13 rutabaga 2
14 quartz 3
15 feldspar 3
16 silica 3
17 gypsum 3
18 hunting 4
19 companion 4
20 herding 4
21 setter 18
22 pointer 18
23 terrier 18
24 poodle 19
25 chihuahua 19
26 shepherd 20
27 collie 20

Terms commonly used with the adjacency model include tree, root, node, subtree, leaf, path, depth and level. There can be one or more trees in the table, and the parent foreign key is NULL for each tree’s root node. A root node is therefore at the “top” of its tree. A node is any entry, while a leaf is any node that has no children, i.e. for which there exists no other node having that node as its parent. A subtree is the portion of the tree “under” any node. The depth of a subtree is the maximum number of levels of subtree beneath that node. These may not be official terminology definitions, but they work for me.

Why is it called a tree when it grows down from the “root” which is at the top? Mere convention.

Now let’s see how a tree or hierarchy can be used to implement a category/subcategory structure.

Working with categories and subcategories

Using the adjacency model to implement categories and subcategories can be reduced to two simple steps:

  1. manage the hierarchical data
  2. display the hierarchical data

Managing the hierarchy is nothing special. Just look again at the table layout. There’s a primary key column (id) and a foreign key referencing it (parentid). Other than that, it’s a dead simple table. Use INSERT, UPDATE, and DELETE as with any other table. Whether we actually declare the foreign key on parentid, which is necessary for referential integrity, is secondary to the basic design. (Referential integrity means that the parent row should exist before the child row referencing it is inserted, and so on. See the article Relational Integrity in the Resources below.)

Displaying the hierarchy is challenging, but not difficult. Categories and subcategories can be handled in HTML in many ways. Current best practice is to use nested unordered lists. For further information, see Listamatic: one list, many options in the Resources below.

Displaying all categories and subcategories: site maps and navigation bars

To display the hierarchy, we must first retrieve it. The following method involves using as many LEFT OUTER JOINs as necessary to cover the depth of the deepest tree. For our sample data, the deepest tree has four levels, so the query requires four self-joins. Each join goes “down” a level from the node above it. The query begins at the root nodes.

select root.name  as root_name
     , down1.name as down1_name
     , down2.name as down2_name
     , down3.name as down3_name
  from categories as root
left outer
  join categories as down1
    on down1.parentid = root.id
left outer
  join categories as down2
    on down2.parentid = down1.id
left outer
  join categories as down3
    on down3.parentid = down2.id
 where root.parentid is null
order 
    by root_name 
     , down1_name 
     , down2_name 
     , down3_name

Notice how the WHERE clause ensures that only paths from the root nodes are followed. This query produces the following result set:

root_name down1_name down2_name down3_name
animal birdie NULL NULL
animal doggie companion chihuahua
animal doggie companion poodle
animal doggie herding collie
animal doggie herding shepherd
animal doggie hunting pointer
animal doggie hunting setter
animal doggie hunting terrier
animal gerbil NULL NULL
animal horsie NULL NULL
animal kittie NULL NULL
mineral feldspar NULL NULL
mineral gypsum NULL NULL
mineral quartz NULL NULL
mineral silica NULL NULL
vegetable carrot NULL NULL
vegetable celery NULL NULL
vegetable potato NULL NULL
vegetable rutabaga NULL NULL
vegetable tomato NULL NULL

Each row in the result set represents a distinct path from a root node to a leaf node. Notice how the LEFT OUTER JOIN, when extended “below” the leaf node in any given path, returns NULL (representing the fact that there was no node below that node, i.e. satisfying that join condition).

As we can see, this result set contains all our original categories and subcategories. If the categories and subcategories are being displayed on a web site, this query can therefore be used to generate the complete site map. An abbreviated query, that goes down only a certain number of levels from the roots, regardless of whether there may be nodes at deeper levels, can be used for the site’s navigation bar.

We can display this sample data using nested unordered lists like this:

  • animal
    • birdie
    • doggie
      • companion
        • chihuahua
        • poodle
      • herding
        • collie
        • shepherd
      • hunting
        • pointer
        • setter
        • terrier
    • gerbil
    • horsie
    • kittie
  • mineral
    • feldspar
    • gypsum
    • quartz
    • silica
  • vegetable
    • carrot
    • celery
    • potato
    • rutabaga
    • tomato

What’s the easiest way to transform the result set into the nested ULs? In ColdFusion, we use nested CFOUTPUT tags, with the GROUP= parameter on all but the innermost list. Very straightforward indeed. In other scripting languages, as the saying goes, your mileage may vary. Take comfort in the fact that once you’ve coded it, you will never have to change your site map page again.

What if the hierarchy is more than, say, three or four levels deep? What if it’s fifteen levels deep? My response to this question is threefold.

First, a query with fifteen self-joins may be a little more tedious to code but most assuredly will not present any difficulty to your database engine.

Second, in certain databases such as Oracle and DB2, recursion is built in, so you can go as many levels deep as you wish—although don’t fool yourself, the coding required to display an arbitrary number of levels is no picnic either. Do not make the mistake of simulating recursion by coding a script module that calls itself, because from the database perspective, this is a series of calls (a query in a loop) and the performance will reflect this.

Thirdly, if you have a tree that goes more than three or four levels deep, you may have difficulty conveying this structure satisfactorily in a visual way. You may want to go back and re-think how you expect your users to actually navigate through the hierarchy. Sometimes the best solution is simply to show no more than three levels, with some sort of visual clue that there are further levels below the nodes shown.

The path to the root: the breadcrumb trail

Retrieving the path from any given node, whether it is a leaf node or not, to the root at the top of its path, is very similar to the site map query. Again, we use LEFT OUTER JOINs, but this time we go “up” the tree from the node, rather than “down.”

select node.name as node_name 
     , up1.name as up1_name 
     , up2.name as up2_name 
     , up3.name as up3_name 
  from categories as node
left outer 
  join categories as up1 
    on up1.id = node.parentid  
left outer 
  join categories as up2
    on up2.id = up1.parentid  
left outer 
  join categories as up3
    on up3.id = up2.parentid
order
    by node_name

Here’s the result set from this query:

node_name up1_name up2_name up3_name
animal NULL NULL NULL
birdie animal NULL NULL
carrot vegetable NULL NULL
celery vegetable NULL NULL
chihuahua companion doggie animal
collie herding doggie animal
companion doggie animal NULL
doggie animal NULL NULL
feldspar mineral NULL NULL
gerbil animal NULL NULL
gypsum mineral NULL NULL
herding doggie animal NULL
horsie animal NULL NULL
hunting doggie animal NULL
kittie animal NULL NULL
mineral NULL NULL NULL
pointer hunting doggie animal
poodle companion doggie animal
potato vegetable NULL NULL
quartz mineral NULL NULL
rutabaga vegetable NULL NULL
setter hunting doggie animal
shepherd herding doggie animal
silica mineral NULL NULL
terrier hunting doggie animal
tomato vegetable NULL NULL
vegetable NULL NULL NULL

Here each row in the result set is a single path, one for every node in the table. On a web site, such a path is often called a breadcrumb trail. (This name is somewhat misleading, because it suggests that it might represent how the visitor arrived at the page, which is not always the case. The accepted meaning of breadcrumb is simply the path from the root.)

In practice, we’d have a WHERE clause that would specify a single node, so in effect, the results above are all of the breadcrumbs in the table.

To display a breadcrumb trail in the normal fashion, from root to node, just display the result set columns in reverse order, and ignore the nulls. For example, let’s say we run the above query for the category “companion” and get this:

node_name up1_name up2_name up3_name
companion doggie animal NULL

The breadcrumb would look like this:

Simple, eh?

Nguồn: http://sqllessons.com/categories.html