Bài viết mới:

Thứ Năm, 16 tháng 3, 2017

Quản lý bộ nhớ cache cho website với Cachewall trên cPanel

Cachewall là 1 bộ nhớ đệm website kết hợp với tường lửa.

Cachewall hoạt động như một máy gia tốc HTTP, được thiết kế đặc biệt để tối ưu hóa hiệu suất trong việc phân phối các nội dung trang web cho khách truy cập.

Bản sao của các tập tin trên website và các trang web của bạn được lưu trữ trên máy chủ và chuyển đến cho khách trong thời gian thực. Điều này cải thiện đáng kể hiệu suất trang web của bạn.

Tường lửa Cachewall tập trung dữ liệu được thu thập qua nhiều mạng để theo dõi các chương trình, tin tặc, kẻ gửi spam và những người dùng độc hại khác. Các dữ liệu được tổng hợp và sau đó được sử dụng để tạo ra một danh sách đen được cập nhật và phân phối cho các đối tượng của Cachewall trong thời gian thực để giúp bảo vệ trang web của bạn.

Cachewall có thể được tìm thấy dưới phần SOFTWARE trong cPanel.


Bảng điều khiển Cachewall cung cấp cho bạn 3 lựa chọn:
  1. Bật (ON) hoặc tắt (OFF) bộ nhớ đệm 
  2. Purge cache để xóa bộ nhớ cache
  3. Kích hoạt chế độ Development Mode (bộ nhớ cache sẽ bị vô hiệu hóa trong vòng 6 giờ, sau 6 giờ bộ nhớ cache sẽ tự động bật lại)

Mình khuyến khích bạn bật bộ nhớ đệm để tăng hiệu suất website. Lựa chọn số 3 bạn nên chọn khi đang sửa chữa CSS hay JS trực tiếp trên host và muốn kiểm tra ngay kết quả website sau khi sửa. Ngày trước mình chưa biết đến phần Cachewall trên cPanel nên mỗi khi sửa file trên host là phải xóa bộ nhớ cache từ trình duyệt rất chi là mất thời gian và ảnh hưởng đến nhiều web khác mà mình đang lưu cache.

Bài viết đến đây là hết. Đăng ký theo dõi blog ở bên dưới website để nhận được thông báo qua email khi có bài viết mới nhé (sau khi nhấn đăng ký thì bạn nhớ vào mail để xác nhận nhé). 

Thứ Sáu, 10 tháng 3, 2017

Hiện chi tiết ngoại lệ trong Entity Framework

Nhiều bạn khi làm việc với Entity Framework trên .NET thường gặp phải lỗi quen thuộc "System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details." phải không nào? 😍


Thông báo ngoại lệ huyền thoại khi làm việc với EF :))


Nội dung của đoạn báo ngoại lệ này có ý nghĩa rằng bạn đã vi phạm 1 ràng buộc nào đó trên 1 hoặc nhiều entities. Một đoạn thông báo khá mơ hồ như vậy khiến nhiều bạn phải vất vả ngồi dò lại code và dò cả các ràng buộc bạn đặt trong cơ sở dữ liệu. Nếu bạn dùng khối catch chung chung để bắt ngoại lệ thì cũng nhận được thông báo như vậy.

Để giải quyết vấn đề này mình sẽ hướng dẫn bạn sử dụng khối try catch sau đây để có thể nhìn thấy rõ ngoại lệ mà bạn gặp phải như là định dạng ngày tháng không hợp lệ, khóa chính bị trùng, độ dài ký tự vượt quá độ dài tối đa, ... Nội dung đoạn try catch này như sau:

        try
        {
            // code của bạn
        }
        catch (DbEntityValidationException ex)
        {
            // Retrieve the error messages as a list of strings.
            var errorMessages = ex.EntityValidationErrors
                    .SelectMany(x => x.ValidationErrors)
                    .Select(x => x.ErrorMessage);
    
            // Join the list to a single string.
            var fullErrorMessage = string.Join("; ", errorMessages);
    
            // Combine the original exception message with the new one.
            var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
    
            // Throw a new DbEntityValidationException with the improved exception message.
            throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
        }

Ý nghĩa đoạn lệnh này như sau. Mình dùng khối catch (DbEntityValidationException ex) để bắt những ngoại lệ liên quan đến ràng buộc trong các entity class, sau đó trong lệnh catch mình sử dụng đối tượng ex và dùng thuộc tính EntityValidationErrors để lấy ra tất cả những lỗi và gán những thông báo lỗi qua 1 biến mảng errorMessages. Sau đó mình đổi mảng thành chuỗi với quy định mỗi phần tử trong mảng sẽ ngăn nhau bởi dấu ; thông qua phương thức string.Join(). Tiếp nữa mình kết hợp thông báo ngoại lệ ban đầu và thông qua ngoại lệ mới và gán qua biến exceptionMessage. Cuối cùng mình dùng lệnh throw để ném ra ngoại lệ cùng 1 thông báo chi tiết về lỗi bạn đang gặp phải.

Công việc còn lại của bạn khi biết rõ ràng lỗi là dễ dàng và đỡ tốn thời gian hơn nhiều so với việc đi dò từng đoạn lệnh và debug đi debug lại. Mong rằng bài viết sẽ giúp các bạn thật nhiều trong các dự án sắp tới 😃.

Thứ Bảy, 4 tháng 3, 2017

Phân trang trong ASP.NET MVC bằng thư viện PagedList.MVC

Sau bài viết Làm thế nào để phân trang dữ liệu với PHP thì mình tiếp tục ra mắt bài hướng dẫn Phân trang trong ASP.NET MVC bằng thư viện PagedList.MVC siêu hot này. Bài viết này sẽ giúp các bạn đang học và làm việc với ASP.NET MVC có thể dễ dàng thực hiện chức năng phân trang sử dụng thư viện PagedList.MVC được tải về từ công cụ NuGet Package trong Visual Studio.



Bước 1: Mở giao diện Package Manager Console và nhập lệnh "Install-package PagedList.MVC" để tải thư viện PagedList.MVC vào project


Bước 2: Using namespace PagedListPagedList.MVC trong Controller



Bước 3: Thêm tham số page trong các action mà bạn muốn phân trang đồng thời danh sách truyền qua view phải được ép thành kiểu IPagedList<T> bằng phương thức ToPagedList(). Trong phương thức này bạn truyền vào 2 giá trị là trang đang đứng lấy từ tham số pagesố lượng record trên 1 trang. Trong ví dụ này mình để 20 record trên 1 trang.

Cũng cần chú ý rằng thư viện PagedList.MVC yêu cầu bạn phải sắp xếp danh sách trước khi gọi phương thức ToPagedList() nên trong ví dụ dưới mình đã sắp xếp danh sách giảm dần theo SanPhamID bằng phương thức quen thuộc OrderByDescending. Đây là đoạn code tổng quát:




Giải thích cho bạn luôn  lệnh page ?? 1, lệnh này đơn giản kiểm tra nếu giá trị page = null thì sẽ gán page = 1 bởi vì mặc định người dùng lần đầu vào trang thì họ sẽ ở trang 1.

Bước 4: Mở view lên và khai báo 2 namespace PagedList và PagedList.MVC trong view. Để hiển thị giao diện phân trang chúng ta dùng phương thức Html.PagedListPager(). Phương thức này đòi hỏi bạn truyền vào 2 đối số là danh sách dữ liệu và đường dẫn URL khi người dùng click vào button phân trang (tham số thứ 2 bạn truyền vào bằng lambda expression nhé). Đây là đoạn lệnh trong view của mình cho bạn tham khảo



Vậy là đã xong các bước sử dụng thư viện PagedList.MVC thực hiện chức năng phân trang trong ASP.NET MVC. Chúc bạn thực hành thành công.

Chú ý: Mình có nhận dạy kèm ASP.NET MVC từ cơ bản đến nâng cao với học phí phù hợp. Yêu cầu nắm vững C# và SQL căn bản. Chi tiết xin liên hệ facebook: https://www.facebook.com/aituan.nguyen. Cảm ơn bạn đã quan tâm.

Thứ Ba, 28 tháng 2, 2017

Hướng dẫn publish source web ASP.NET MVC

Bài viết này hướng dẫn bạn publish (xuất bản) web ASP.NET MVCupload lên host



Bước 1: Mở project của bạn lên và click button "Show All Files" trên khung Solution Explorer để hiển thị toàn bộ file trong thư mục. 

Click "Show All Files"

Include những thư mục hoặc file bị mờ vào project (ngoại trừ 2 thư mục bin và obj vì 2 thư mục này không cần thiết phải include) bằng cách click phải vào thư mục hoặc file bị mờ và chọn "Include In Project".

Include In Project

Và cũng cần phải xóa bỏ những file không còn tồn tại ở thư mục nhưng vẫn hiện ở project. Những file này sẽ có hình cảnh báo màu vàng ở icon. 

Xóa những file không còn tồn tại trong project

Bước 2: Tạo 1 thư mục bất kỳ để chứa source sẽ được publish ra. Ở bài viết này mình sẽ tạo 1 thư mục có tên là publish_ContosoUniversity và để ở thư mục H ở máy mình.

Bước 3: Click phải vào project chọn Publish. Cửa sổ Publish Web hiện ra, bạn chọn Custom sau đó đặt tên Profile và click OK.

Đặt tên profile


Bước 4: Chọn publish method là File System. 

Bước 5: Click button ... và chọn đến thư mục bạn vừa tạo. Ở đây mình sẽ chọn đến thư mục Publish_ContosoUniversity ở ổ H. Sau đó click Next.

Bước 6: Click Publish để tiến hành publish source web ra thư mục bạn tạo. Thao tác này nhanh hay chậm tùy thuộc vào project của bạn nặng hay nhẹ. 

Sau khi xong 6 bước trên bạn sẽ nhận được thông báo "Publish Successfully" như hình dưới.



Kiểm tra thư mục bạn tạo để chứa source publish, bạn sẽ thấy như sau:

Như bạn thấy là tất cả các file .cs trong project đã được mã hóa thành file ContosoUniversity.DLL ở thư mục bin. Đây là 1 trong những lý do chứng minh rằng ASP.NET bảo mật hơn PHP vì không để lộ source code trên host.

Bây giờ bạn chỉ cần upload toàn bộ nội dung trong thư mục này lên host là xong. Chú ý rằng nếu bạn có tạo database trên host thì bạn phải sửa connectionstring trong file Web.config  theo connectionstring được cung cấp trên host nhé. 

Còn nếu trong quá trình sử dụng website bạn có nhu cầu thay đổi source code C# và muốn cập nhật lại lên host thì đơn giản bạn chỉ copy và paste file bin/<tenprojectcuaban>.DLL thôi.

Hy vọng bài viết giúp ích cho bạn. Hẹn gặp lại ở các bài viết tiếp theo trên blog.

Thứ Sáu, 24 tháng 2, 2017

Học lập trình trực tuyến cùng chuyên gia tại kyna.vn


Nếu bạn đang tìm kiếm 1 website học lập trình trực tuyến nội dung chất lượng, học phí phù hợp thì kyna.vn là 1 điểm đến đáng tin cậy cho bạn. Mình đã học qua nhiều khóa tại đây và đánh giá cao website này. Mình xin giới thiệu các khóa học lập trình bên dưới kèm theo mã giảm giá 40% học phí: AITUAN40

Cách đăng ký mua khóa học rất đơn giản bạn chỉ cần click vào link của khóa học muốn học sau đó ấn đăng ký để thêm vào giỏ hàng. Thực hiện nhập mã giảm giá bên trên và chọn phương thức thanh toán là xong.

Danh sách khóa học


Lập trình IOS (300.000 đ)















Responsive Design (100.000 đ)












Java cơ bản (400.000 đ)



Java nâng cao (300.000 đ)

Ngoài ra còn nhiều khóa học rất hay khác mà bạn có thể xem tại địa chỉ https://kyna.vn/danh-sach-khoa-hoc/it-va-lap-trinh. Chúc các bạn học tốt 😊. Mọi thắc mắc các bạn comment bên dưới nhé. 

Thứ Hai, 20 tháng 2, 2017

Tạo Popup Social cho website

Khi các bạn vào một số website tin tức, blog nổi tiếng bạn sẽ thường thấy website có những nút social để người dùng có thể like hoặc share website của bạn lên mạng xã hội. Ở bài viết này mình sẽ hướng dẫn bạn tạo 1 Popup Social chứa nút like và share của Facebook và Google Plus cực cool cho website của bạn, điều này sẽ giúp ích rất nhiều trong việc SEO.


Bước 1: Dán đoạn mã sau vào trong thẻ body ở trang web của bạn:


<div id="fb-root"></div>
<script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/vi_VN/sdk.js#xfbml=1&version=v2.8&appId=appIdFacebookcuaBan";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script> 
<div class="popupSocial" >
<div class="fb-like" data-href="UrlTrangweb" data-layout="box_count" data-action="like" data-size="small" data-show-faces="true" data-share="true"></div>
<br/><br/>
<div style="width:60px">
<script src="https://apis.google.com/js/platform.js" async defer></script>
<g:plusone></g:plusone>
</div>
</div>

Bạn nhớ thay thế appIdFacebookcuaBan bằng ID Ứng Dụng của bạn trong trang developers.facebook.com và UrlTrangweb bằng URL trang web của bạn nhé.

Bước 2: Bổ sung đoạn CSS sau vào trang web:

.popupSocial{
z-index:999; text-align:center;
background:#2c4584; position:fixed; 
top:45%; left:10px; padding:20px 10px; 
border:1px solid #333; border-radius:10px;
  } 
@media screen and (max-width:768px){
 .popupSocial{
display:none;
}


Ở đoạn CSS trên bạn có thể thay đổi giá trị của thuộc tính background để đổi màu nền của popup, hoặc thay thế  lệnh left:10px; thành lệnh right:10px; nếu muốn popup neo về bên phải trang web thay vì bên trái .

Khi chạy website trên điện thoại sẽ xảy ra trường hợp là popup che mất trang vì vậy mình đã bổ sung đoạn lệnh @media screen ... để ẩn popup đổi với các thiết bị có chiều rộng <= 768px


Kết quả là bạn sẽ có 1 popup social giống như blog Chuyên lập trình này vậy. 😋

Thứ Bảy, 11 tháng 2, 2017

Làm thế nào để phân trang dữ liệu với PHP

Làm thế nào để phân trang dữ liệu với PHP là một câu hỏi mà nhiều bạn mới học PHP thường đặt ra. Ngày hôm nay mình sẽ hướng dẫn bạn viết code để thực hiện điều đó.


Tạo file Paginator.class.php


Đầu tiên chúng ta cần tạo 1 class Paginator như sau:

<?php
class Paginator {
     private $_conn;
        private $_limit;
        private $_page;
        private $_query;
        private $_total;
}

Sau đó bổ sung cho class thêm 1 constructor.


public function __construct( $conn, $query ) {
    $this->_conn = $conn;
    $this->_query = $query;
    $rs= $this->_conn->query( $this->_query );
    $this->_total = $rs->num_rows;
}

Khá đơn giản phải không? Constructor gán giá trị cho thuộc tính $_conn$_query bằng 2 tham số $conn$query được truyền vào và thực hiện lệnh truy vấn cần thiết, tiếp theo là gán tổng số record được lấy từ lệnh truy vấn và gán qua thuộc tính $_total. Thuộc tính $_total rất cần thiết để tạo ra các liên kết phân trang.

Lưu ý: ở ví dụ mình không có thực hiện bất kỳ việc bắt lỗi và không tạo bất kỳ ràng buộc nào cho các tham số nhưng trong một ứng dụng thực tế thì bạn cần bổ sung thêm việc bắt lỗi và tạo các ràng buộc cần thiết cho tham số để ứng dụng web được bảo mật tốt nhất.

Lấy dữ liệu theo trang


Bây giờ chúng ta hãy tạo một phương thức để đánh số trang dữ liệu và lấy dữ liệu theo số trang. 

public function getData( $limit = 10, $page = 1 ) { 
    $this->_limit   = $limit;
    $this->_page    = $page;
    if ( $this->_limit == 'all' ) {
        $query      = $this->_query;
    } else {
        $query      = $this->_query . " LIMIT " . ( ( $this->_page - 1 )
* $this->_limit ) . ", $this->_limit";
    }
    $rs             = $this->_conn->query( $query );
    while ( $row = $rs->fetch_assoc() ) {
        $results[]  = $row;
    }
   $result         = new stdClass();
    $result->page   = $this->_page;
    $result->limit  = $this->_limit;
    $result->total  = $this->_total;
    $result->data   = $results;
    return $result;
}

Tham số $limit đại diện cho số lượng record hiển thị trên trang và tham số $page đại diện cho số trang mà bạn đang truy cập. Theo mặc định mình gán $limit = 10, bạn có thể thay đổi giá trị này tùy ý muốn. Đoạn lệnh if else để kiểm tra xem nếu người dùng muốn lấy dữ liệu theo trang thay vì xem toàn bộ. Nếu người dùng muốn xem dữ liệu theo trang thì mình tiến hành nối thêm chuỗi LIMIT ... để lấy dữ liệu theo trang đó dựa vào lệnh truy vấn SQL. Cuối cùng là thực hiện truy vấn cơ sở dữ liệu theo biến $query, gán qua đối tượng result và trả về kết quả.

Hiển thị liên kết phân trang


Việc hiển thị liên kết phân trang là rất quan trọng. Bạn phải code để các liên kết được hiển thị hợp lý khiến người dùng dễ sử dụng. Ở bài viết này thì bạn không cần lo về vấn đề này vì các liên kết được tạo ra sẽ rất hợp lý và logic.

Bây giờ chúng ta sẽ tạo phương thức để có được các liên kết.

<?php
public function createLinks( $links, $list_class ) {
    if ( $this->_limit == 'all' ) {
        return '';
    }
    $last       = ceil( $this->_total / $this->_limit );
    $start      = ( ( $this->_page - $links ) > 0 ) ? $this->_page - $links
: 1;
    $end        = ( ( $this->_page + $links ) < $last ) ?
$this->_page + $links : $last;
    $html       = '<ul class="' . $list_class . '">';
    $class      = ( $this->_page == 1 ) ? "disabled" : "";
    $html       .= '<li class="' . $class . '"><a href="?limit='
.$this->_limit . '&page=' . ( $this->_page - 1 )
. '">&laquo;</a></li>';
    if ( $start > 1 ) {
        $html   .= '<li><a href="?limit=' . $this->_limit .
'&page=1">1</a></li>';
        $html   .= '<li class="disabled"><span>...</span></li>';
    }
    for ( $i = $start ; $i <= $end; $i++ ) {
        $class  = ( $this->_page == $i ) ? "active" : "";
        $html   .= '<li class="' . $class
. '"><a href="?limit=' . $this->_limit
. '&page=' . $i . '">' . $i . '</a></li>';
    }
    if ( $end < $last ) {
        $html   .= '<li class="disabled"><span>...</span></li>';
        $html   .= '<li><a href="?limit=' . $this->_limit . '&page='
. $last . '">' . $last . '</a></li>';
    }
    $class      = ( $this->_page == $last ) ? "disabled" : "";
    $html       .= '<li class="' . $class . '"><a href="?limit='
. $this->_limit. '&page=' . ( $this->_page + 1 )
. '">&raquo;</a></li>';
    $html       .= '</ul>'; 
    return $html;
}

Index.php 


Bây giờ chúng ta sẽ tạo ra tập tin index.php để sử dụng class Paginator. Nội dung file index.php chỉ đơn giản như thế này: 

<!DOCTYPE html>
    <head>
        <title>PHP Pagination</title>
        <link rel="stylesheet" href="css/bootstrap.min.css">
    </head>
    <body>
        <div class="container">
                <div class="col-md-10 col-md-offset-1">
                <h1>PHP Pagination</h1>
                <table class="table table-striped table-condensed
table-bordered table-rounded">
                        <thead>
                                <tr>
                                <th>City</th>
                                <th width="20%">Country</th>
                                <th width="20%">Continent</th>
                                <th width="25%">Region</th>
                        </tr>
                        </thead>
                        <tbody></tbody>
                </table>
                </div>
        </div>
        </body>
</html>


Sử dụng Paginator


Sử dụng class Paginator bằng cách thêm đoạn lệnh sau vào đầu file index.php:

<?php
    require_once 'Paginator.class.php';
    $conn       = new mysqli( '127.0.0.1', 'root', 'root', 'world' );
    $limit      = ( isset( $_GET['limit'] ) ) ? $_GET['limit'] : 25;
    $page       = ( isset( $_GET['page'] ) ) ? $_GET['page'] : 1;
    $links      = ( isset( $_GET['links'] ) ) ? $_GET['links'] : 7;
    $query      = "SELECT City.Name, City.CountryCode, Country.Code,
Country.Name AS Country, Country.Continent,
Country.Region FROM City, Country
WHERE City.CountryCode = Country.Code";
    $Paginator  = new Paginator( $conn, $query );
    $results    = $Paginator->getData( $limit, $page );
?>

Hiển thị kết quả


Bây giờ để hiển thị kết quả thu được thì bạn thêm đoạn lệnh sau vào thẻ tbody:

<?php for( $i = 0; $i < count( $results->data ); $i++ ) : ?>
        <tr>
                <td><?php echo $results->data[$i]['Name']; ?></td>
                <td><?php echo $results->data[$i]['Country']; ?></td>
                <td><?php echo $results->data[$i]['Continent']; ?></td>
                <td><?php echo $results->data[$i]['Region']; ?></td>
        </tr>
<?php endfor; ?>


Liên kết phân trang


Để hiển thị các liên kết phân trang bên dưới table thì bạn thêm đoạn lệnh sau vào dưới thẻ table:

<?php echo $Paginator->createLinks( $links, 'pagination pagination-sm' ); ?>

Kết quả ta được như hình dưới.

Project demo của bài viết bạn có thể tải về tại địa chỉ goo.gl/xEOLy5content_copyCopy short URL. Hi vọng bài viết sẽ giúp bạn thật nhiều. Hẹn gặp lại ở các bài viết PHP khác.