by oclockvn at 12:47 AM 09/29/2016

Sử dụng ajax trong ASP.NET MVC

ajax là gì?

AJAX = Asynchronous JavaScript and XML

Ajax là kỹ thuật web được sử dụng ở client-site dùng để gửi-nhận request-response với server một cách bất đồng bộ. Nếu khái niệm này hơi rắc rối, bạn có thể hiểu ajax được sử dụng khi bạn muốn lấy dữ liệu từ server nhưng không muốn reload lại toàn bộ trang web.

đơn giản là thế này nhé!

Đây là 1 response khi tải 1 page của 1 website

web response

bạn có thấy cái đống files bùi nhùi (html/css/js/images/fonts...) đó không, nó là tất cả resources của website được trả về từ server để render ra webpage. Càng nhiều resources, webpage càng render chậm - và dĩ nhiên, performance sẽ giảm đi.

Để không cho trang web load những resources không cần thiết, kỹ thuật ajax được đưa ra. Với kỹ thuật này, bạn chỉ cần gửi request lên server và dữ liệu được trả về chỉ gồm những data bạn muốn.

ajax response

jquery ajax

Ajax được thực hiện bằng đối tượng XMLHtttpRequest, tuy nhiên jquery đã đóng gói các chức năng vào 1 method để có thể sử dụng ajax 1 cách dễ dàng và thuận tiện nhất: $.ajax(); Do vậy, bạn cần phải host jquery để có thể sử dụng được ajax (bằng jquery).

cấu trúc của $.ajax()

Cấu trúc đơn giản nhất của ajax được thể hiện như sau:

<script>
    var options = {
        url: '/server/action',
        data: {},
        method: 'get',        
        success: function(response) {},
        error: function(jqXHR, status, error){}
    };

    $.ajax(options);
</script>

Các đối tượng cơ bản trong 1 request của ajax bao gồm:

  • url: request sẽ gọi tới url này trên server để xử lý
  • data: dữ liệu được truyền lên server
  • method: là http method get hoặc post. Mặc định nếu không chỉ định thì method='get'
  • success: callback được xử lý nếu request thành công (mình sẽ giải thích callback sau).
  • error: callback được xử lý nếu request thất bại.

bạn có thể tham khảo các settings khác của option tại trang document của jquery ajax

Đôi khi ajax được viết gọn lại là:

<script>
    // get request
    $.get('/server/action', function(response){});

    // post request
    $.post('/server/action', data: {}, function(response){});
</script>

Tuy 2 cách viết này ngắn gọn, nhưng mình vẫn thích cách viết đầy đủ hơn vì bạn có thể setting nhiều options trong 1 request hơn.

Trên đây là cấu trúc cơ bản để thực hiện 1 ajax request, mình sẽ giải thích kỹ hơn về các tham số và callback ở phần tiếp theo - ajax với asp.net mvc (nói mvc* cho ngắn gọn)

ajax trong asp.net mvc - ví dụ 1: server time

Yêu cầu: lấy dữ liệu thời gian từ server và hiển thị lên website.
Giải pháp: cứ mỗi giây, request (ajax) lên server để lấy thời gian và hiển thị lên website.

Mình sẽ không nói về asp.net mvc nhé, cái đó sẽ được nói ở những bài khác. Ở đây mặc định là bạn đã biết mvc.

Với yêu cầu này, nếu không sử dụng ajax thì bạn có thể làm đơn giản bằng cách dưới đây:

Trong controller

home controller

Trong View

index view

Kết quả

index result

Bạn có thể thấy, mỗi giây thì thời gian lại được cập nhật, tuy nhiên page lại refresh rất...khó chịu.

Sử dụng bằng ajax

Trong Controller

home controller

Trong View

index view

Và kết quả đúng như mong đợi, cứ mỗi giây** thì thời gian lại được cập nhật 1 lần, và page vẫn không hề reload bởi dữ liệu trả về chỉ là string chứa ngày tháng của server

server time

ajax success callback

Trong request đơn giản này chỉ chứa 2 tham số, và nó cũng không có gì khó hiểu:

  1. url: dẫn đến controller Home, action Timer để xử lý (mvc route Controller/Action)
  2. success: callback được gọi sau khi server xử lý xong và trả về kết quả.

callback ở đây chỉ đơn giản là 1 function, mà function này được invoke khi nào server xử lý thành công và trả về kết quả với status = 200.

Để hiểu rõ hơn thì mình sẽ chỉnh sửa lại controller và script như sau:

Trong Controller

sleep action

Trong View

log response

Kết quả

log response

Giải thích về script:

  • javascript là single thread và code được thực thi từ trên xuống dưới - 1-cách-lần-lượt. Từ dòng 10 - 16, khai báo 1 object dùng để config cho ajax call, ở đây gồm 1 url và 1 callback function.
  • Đến dòng 18, ajax thực hiện request lên server. Tuy trên server lại sleep 3s, nhưng dưới client js vẫn tiếp tục chạy đến dòng 20 và in ra câu lệnh hello world.
  • setInterval vẫn tiếp tục chạy (interval = 1000ms), ajax vẫn gửi dữ liệu lên server, và server vẫn delay 3s. Sau đó thì 1..2..3 sau khi sleep(3000), server return Content() và response về client, success callback được gọi.
  • Do đó mới có kết quả của console: sau 3 lần in ra câu hello world mới tới 1 lần in ra thời gian từ server.

Hàm callback chính là cơ chế bất đồng bộ (không đồng bộ) của ajax. Để hiểu rõ hơn cơ chế bất đồng bộ này, hãy xem tiếp ví dụ bên dưới:

async callback

Ở dòng 8 khai báo 1 biến, dòng 13 và 19 đều in ra giá trị của biến đó. Do cơ chế bất đồng bộ, sau khi gọi ajax ở dòng 17, script vẫn tiếp tục chạy xuống dòng 19 và in ra giá trị result, tuy nhiên lúc này result vẫn chưa có giá trị nào cả. Sau khi server trả về kết quả, success callback được gọi, result được gán giá trị ở dòng 12, và tới dòng 13, result đã nắm giữ giá trị nào đó từ server trả về:

result console

Có thể trước giờ khi chưa làm quen với cơ chế bất đồng bộ bạn sẽ hơi khó hình dung được chỗ này vì nó không đúng quy trình :)) Nếu đã từng làm việc với Thread, Task trong C#, bạn sẽ dễ dàng liên tưởng được 2 khái niệm task (async - await) và ajax (Asynchronous Javascript and XML) hoặc ngược lại nhé :))

các callback khác của ajax

Ngoài success callback, ajax còn có 2*** callback khác nữa

  • success: callback khi trả về dữ liệu thành công.
  • error: callback khi request thất bại.
  • complete: callback luôn được gọi cho dù success hay error.

Nó đại loại thế này nè ^^:

try {
    // success
} catch (Exception ex) {
    // error
} finally {
    // final
}

Cách khai báo cũng tương tự như success callback

<script>
    $.ajax({
        url: '/server/action',
        success: function(response) {},
        error: function(xhr, stt, err) {},
        complete: function(){}
    });
</script>

Hoặc bạn cũng có thể viết tách rời ra như thế này:

<script>
    var req = $.ajax({url: '/server/action'});

    req.success(function(){});
    req.error(function(){});
    req.complete(function(){});

    // even more callback registered
    req.success(function(){});
    req.success(function(){});
</script>

Sở dĩ bạn có thể viết cách tách rời là vì $.ajax trả về 1 promise object, và promise có các phương thức có thể "gọi lại sau". Lợi thế của cách viết này là bạn có thể đăng ký nhiều callback, và hơn thế nữa là bạn có thể làm những cái request lần lượt như thế này (1 bài nào đó mình sẽ nói tới cái này):

<script>
   $.when($.ajax({})).then($.ajax({})).then($.ajax({}));
</script>

Chú ý: Đối với các version khác nhau của jquery, các callback có tên đôi chút khác nhau, ví dụ như:

<script>
    $.ajax({
        url: '/server/action',
        done: function(response){}, // = success
        fail: function(xhr){},      // = error
        alway: function(){}         // = complete
    })
</script>

ajax và ActionResult

Trong mvc có 2 (+1) loại ActionResult có thể làm việc với ajax

  1. ContentResult, trả về thông qua hàm Content()
public ActionResult AjaxContent()
{
    return Content("this is a string content");
}
  1. JsonResult, trả về thông qua hàm Json
public ActionResult JsonContent()
{
    return Json("this is a json string", AjaxRequestBehavior.AllowGet);
}

Đây là phương thức hay được sử dụng nhất, đối tượng response trong success callback chính là object được trả về từ hàm Json này. Ví dụ như sau:

Trong controller

public ActionResult JsonResponse()
{
    var resp = new {
        code = 1, 
        msg = "success",
        data = new List<int>{1, 2, 3}
    };

    return Json(resp, AjaxRequestBehavior.AllowGet);
}

Trong script

<script>
    $.ajax({
        url: '/Home/JsonResponse',
        success: function(resp) {
            console.log(resp.code); // --> 1
            console.log(resp.msg); // --> "success"
            console.log(resp.data[1]); // --> 2
        }
    });
</script>
  1. ViewResult, trả về thông qua hàm View()

Bởi vì trả về nguyên cái View thì chả khác gì refresh lại trang (tải hết resouces), cho nên chả ai lại dùng ajax mà trả về View. Tuy nhiên vẫn có trường hợp sử dụng nhưng mình không muốn nhắc tới ở đây.

kết: cơ bản là thế!

Hy vọng với bài viết này, bạn đã nắm được cơ chế hoạt động của ajax, có thể sử dụng ajax cho các tác vụ đơn giản. Trong bài tiếp theo mình sẽ thực hiện 2 ví dụ sử dụng ajax trong mvc thường được sử dụng nhiều nhất: xóa phần tử và search ajax.

Nếu có gì thắc mắc, bạn có thể comment trực tiếp dưới đây hoặc liên lạc với mình. Mình sẽ giải đáp hết mình trong khả năng ^^!

  • 1
  • 2660
  • 7
relate posts
by {{relate.UpdatedBy}} at 02/21/2018

{{relate.Title}}

  • {{relate.TotalComment}}
  • {{relate.View}}
  • {{relate.AveragePoint}}
[{{postCtrl.comments.length}}] comments
all comments {{ postCtrl.isHiddenComment ? 'show comments' : 'hide comments' }}
what do you want to say?

(*) markdown supported with html disabled