Chủ Nhật, 17 tháng 4, 2011

Tìm hiểu về Session, ViewState, ControlState, HttpContext.Current, Shared/Static Object.









Đối tượng có vòng đời ngắn nhất là HttpContext.Current chỉ tồn tại trên Request, sẽ kết thúc khi Server trả về một Response.

Đối tượng ViewState nằm trên cả Request và Response. Đối tượng này được lưu trên Client thông qua biến ẩn HiddenField và được mã hóa để tránh nhòm ngó.

Một đối tượng khác tương đương ViewState là ControlState. ControlState được sử dụng để lưu lại hành vi của Control và cũng được lưu trên Client thông qua biến ấn Hidden Field. Khi tắt ViewState trên Client thì các thuộc tính được lưu trong ViewState sẽ “chết”, trong khi ControlState vẫn tồn tại vì được bảo vệ trong Control.

Đối tượng Session có mức độ phủ rộng hơn ViewState, nó tồn tại trên bất cứ postback nào ở bất cứ trang nào. Đối tượng Session chỉ kết thúc vòng đời của nó khi shutdown server hoặc tắt trình duyệt. Khác với đối tượng ViewState, đối tượng Session được lưu trên Server nên bảo mật hơn. Nhược điểm là đối tượng Session chiếm nhiều tài nguyên Server. Server sẽ quá tải nếu có nhiều Client gửi Request cùng một lúc.

Thứ Tư, 13 tháng 4, 2011

Why do most Vietnamese developers usually retire after 30 years old?

Quite a few years ago, most developers choose IT as a good start to grow up, earn money and become a boss soon after. That's a reason why many IT developers retire after 30 years old. Even worst, if they haven't promoted to a post of manager in that age, they prepare to drop out of his company, burn their bridges behind them with the hope to change their life, such as Stock Exchange, Trading... Some developers take a Master course in another field like MBA just after graduation or join the first company not long ago. This is very common in Vietnam.

Vietnamese people has strength in Math background, one of important factors to make a good developer. However, it’s not enough. Hard-working, persistence, good attitudes, passion, energy… are all that sum up to good performing developer. In the developing countries like Vietnam, China…, people has tendency to choose the less hard working job but high earning professional. Having worked for IT industry for a couple of years, people will feel the stress in doing software with pretty tightening schedule. Normally, developers have to work more than 8 hours a day to get the job done, especially the projects that usually go down the drain.

Most developers do not notice that if they don't have the so-called "passion" to work on something, they cannot success in any area of business, not in addition to IT only. People of all kinds run into same problem as they think that they come to work for earning money mostly. In fact, in any kinds of job, people always find the fun in it to get the job done.

Thứ Hai, 4 tháng 4, 2011

20 typical answer from developers to tester

20. "That’s weird…"
 19. "It’s never done that before."
 18. "It worked yesterday."
17. "How is that possible?"
 16. "It must be a hardware problem."
 15. "What did you type in wrong to get it to crash?"
 14. "There is something funky in your data."
 13. "I haven’t touched that module in weeks!"
 12. "You must have the wrong version."
 11. "It’s just some unlucky coincidence."
 10. "I can’t test everything!"
 09. "THIS can’t be the source of THAT."
 08. "It works, but it hasn’t been tested."
 07. "Somebody must have changed my code."
 06. "Did you check for a virus on your system?"
 05. "Even though it doesn’t work, how does it feel?
 04. "You can’t use that version on your system."
 03. "Why do you want to do it that way?"
 02. "Where were you when the program blew up?"
 01. "It works on my machine" 

Chủ Nhật, 23 tháng 1, 2011

Why does object.style.background='url()' cause postback?


Look at the following code:

Here is what you figure it out:









Problem is that each time focus is set for TextBox, a postback occurs. You can realize
it if you place a debug point in Page_Load()
protected void Page_Load(object sender, EventArgs e)
    {
    }



It runs into same problem even in every browser. I have no idea of what the reason might be, nor how to solve it. But I came across a workaround when I play with CSS. Here is what I'm gonna show it:

Firstly, place TextBox background reset block into CSS and change style from JavaScript through CssClass:


    



Secondly, replace onfocus="this.style.background = 'url()';" by onfocus="txtOnFocus(this);"


Now, it works just fine.


Thứ Năm, 6 tháng 1, 2011

Bảo mật nội dung trang web với các thẻ "onselectstart" và "ondragstart"

Thi thoảng gặp những trang web "cứng đầu" không cho select hoặc copy nội dung của nó (vì bảo vệ bản quyền). Trong trường hợp đó chúng ta thường Save As nó về máy, view HTML code ra, tìm cách xóa sạch trơn các script lẫn trong đống hỗn độn dữ liệu và HTML markup. Nhược điểm của cách này là mất khá nhiều thời gian và thường là thiếu kiên nhẫn! Dưới đây sẽ trình bày 1 cách để tìm đúng "huyệt" và sau đó xóa nó đi, khi đó sẽ copy thoải mái.

<body topmargin="0" leftmargin="0" rightmargin="0" ondragstart="return false" onselectstart="return false" >

Ở đây sẽ tìm tất cả "onselectstart" và xóa đi là OK.

Ngoài ra các đoạn text trong thẻ div cũng có thể được bảo vệ bởi thuộc tính -moz-user-select (mặc định là Auto).
Chỉ việc đổi nó sang None là sẽ bỏ đi áo giáp bảo vệ này.
<div style="-moz-user-select:none;" >


Tương tự như vậy, thẻ "ondragstart" sẽ bảo vệ việc kéo nội dung (text, image...) và thả sang vị trí mới (thí dụ local directory).


Về phía người thiết kế web site, lợi dụng đặc điểm này để có thể thiết kế cách bảo mật nội dung site. Có thể thông qua CSS hoặc JavaScript. Đối với JavaScript, hàm dưới đây được xây dựng để tạo ra giáp bảo vệ cho nội dung. Nếu không thể tìm thấy sự file JavaScript (thí dụ đã bị che dấu trên server thông qua HttpHandler) thì lớp bảo vệ càng khó bị phá vỡ.

function disableSelection(target){
if (typeof target.onselectstart!="undefined") //IE route
target.onselectstart=function(){return false}

else if (typeof target.style.MozUserSelect!="undefined") //Firefox route
target.style.MozUserSelect="none"

else //All other route (ie: Opera)
target.onmousedown=function(){return false}

target.style.cursor = "default"
}

Khác nhau giữa Page.ClientScript và ScriptManager?

Có 2 cách đăng ký client-script trên code-behind:
1. Thông qua Page.ClientScript
Thí dụ: Page.ClientScript.RegisterStartupScript(..)
2. Thông qua ScriptManager
Thí dụ: ScriptManager.RegisterStartupScript(..)

Một số câu hỏi đặt ra:

1. Hai cách này khác nhau như thế nào?
2. Khi nào thì nên sử dụng ScriptManager thay vì Page.ClientScript?
3. Khi nào thì sử dụng Page.ClientScript có lợi hơn?

Trước hết, hãy cùng xem lại định nghĩa của 2 đối tượng này:

The ScriptManager is the key component that coordinates the use of JavaScript for the Microsoft AJAX Library.
Page.ClientScript can be used to append some small function in aspx page (validation, alert and so on)

Sau đây là các khác nhau chính giữa các hàm đăng ký client-script trên 2 đối tượng Page và ScriptManager:

1. ScriptManager được sử dụng chỉ khi trên trang Web có bật tính năng Ajax và đã khai báo một đối tượng ScriptManager trên đó.
2. Đối với Page.ClientScript, nếu Control đã nằm sẵn trong UpdatePanel ngay từ đầu (lúc nạp trang) và client-script gần như luôn cố định, thì có thể sử dụng các phương thức đăng ký script của đối tượng Page. Nói một cách khác, nếu script không thay đổi “động” (dựa trên thiết kế để xác định khả năng “động” hay “tĩnh”) và không được gọi trực tiếp sau mỗi “async postback”, thì có thể đăng ký với đối tượng Page. Ngược lại nếu script thay đổi động (khi view source sẽ không nhìn thấy scrip này), được đăng ký tại các thời điểm run-time đặc biệt sau mỗi lần “async postback” xảy ra, thì nên sử dụng các phương thức đăng ký của ScriptManager.


Có một sự khác nhau khác liên quan đến vị trí chèn script. Xem xét 2 thí dụ sau:
Page.ClientScript.RegisterStartupScript(GetType(Page), “myscript”, script)
và
ScriptManager.RegisterClientScriptBlock(Page, GetType(Page), “myscript”, script, True)

Sự khác nhau giữa hai thí dụ trên là: Thí dụ đầu sẽ đặt mã script ở cuối trang. Còn thí dụ sau sẽ đặt mã script ngay sau thẻ .
Khác nhau thứ hai là thí dụ đầu tiên cần phải đưa cặp thẻ vào mã script. Trong khi thí dụ thứ hai các thẻ này sẽ được tự động đưa vào. Giả sử có đoạn code chi tiết như sau:


Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _

Handles Me.Load

Dim script As String

If Not Page.IsPostBack Then

script = ""

Page.ClientScript.RegisterStartupScript(GetType(Page), "focus4", _

script)

script = "alert('Alert message one');" //Không cần đưa vào cặp thẻ

ScriptManager.RegisterClientScriptBlock(Page, GetType(Page), _

"item11", script, True)

End If

End sub

Trong thí dụ này sẽ khởi động 2 Message Box khi bắt đầu nạp trang. Theo thứ tự thì “Alert message two” được biên dịch đầu tiên, nhưng lại được gọi sau message “Alert message one” khi chạy run-time.

Thứ tự xuất hiện trên chỉ là sự khác nhau nhỏ về mặt kiến trúc, và có ảnh hưởng một chút đến hành vi của các control. Sự khác nhau chính vẫn là khả năng “động” của mã script khi được đăng ký theo các Control. Một lưu ý hết sức quan trọng là trong các ứng dụng Ajax sử dụng UpdatePanel, các control xuất hiện trong UpdatePanel có thể là động, thí dụ như chuyển từ ViewMode sang EditMode làm xuất hiện InputControl, hoặc các Control được nạp sau (LazyLoad)… Khi đó nếu sử dụng các phương thức đăng ký của đối tượng Page, chương trình sẽ không chạy đúng và gặp các lỗi lạ... Muốn chương trình chạy đúng, hãy luôn sử dụng các phương thức đăng ký của ScriptManager.

Ref:
http://aspalliance.com/1546_Implementing_style_sheet_code_dynamically.all
http://forums.asp.net/p/1114302/1731285.aspx

Thứ Tư, 13 tháng 1, 2010

Phân biệt Callback và Postback

Callback là 1 dạng đặc biệt của Postback, nhưng hoàn toàn không giống với cách Postback thực hiện. Postback giúp Client liên lạc với Server để thực hiện một tác vụ nào đó và refresh/redraw lại trang HTML. Postback thông thường sẽ gây hiện tượng co giật toàn màn hình (full postback) do phải vẽ lại toàn bộ trang. Đối với postback một phần (partial postback hay async postback), thì hiện tượng co giật không xảy ra do có một đối tượng JavaScript (ScriptManager) đứng đằng sau để vẽ lại một phần màn hình theo yêu cầu. Tuy nhiên khi trang HTML quá phức tạp với số lượng lớn các thẻ HTML được sinh ra, thì Partial Postback vẫn gây ra hiện tượng co giật nhưng với mức độ nhỏ hơn so với Full-Postback.

Trong khi đó Callback chỉ là một cách triệu gọi (thí dụ gọi hàm) đơn thuần lên server để lấy dữ liệu và đổ vào một thẻ nào đó được đặt trước (Place holder) chứ không refresh lại toàn bộ trang, và do đó cũng không gây ra hiện tượng co giật. Như vậy sẽ không thể dùng Callback để vẽ lại bất cứ một vùng nào của trang HTML. Trên server (code-behind), việc cố gắng update giao diện các Control thì sẽ trở nên vô tác dụng, điều này cũng giống như khi cố gắng update một cái gì đó trên UI tại thời điểm “unload” xảy ra (xem ASP.NET Page LifeCycle) nhưng lúc đó việc Rendering đã hoàn tất và không thực thi bất cứ một yêu cầu cập nhật UI nào. Một nhược điểm của ASP.NET là việc cố gắng cập nhật UI tại thời điểm Unload hoặc Callback đểu không gây ra Exception khiến cho những người mới bắt đầu học ASP.NET mất rất nhiều thời gian để tìm hiểu vì sao việc cập nhật UI lại thất bại!

Chúng ta có thể so sánh vòng đời của Postback và Callback như ở dưới đây. Có thể thấy là chúng giống nhau ở hầu hết các giai đoạn, trừ các giai đoạn Rendering vì Callback không tham gia thực hiện việc update UI. Một lưu ý quan trọng là khi Callback xảy ra, giá trị của ViewState không bao giờ thay đổi, tức là khi cố gắng thay đổi giá trị của ViewState trên server khi Callback xảy ra, thì giá trị ViewState vẫn giữ nguyên.





Có thể cập nhật một vùng của trang Web với Callback?
Hoàn toàn được. Nhưng chúng ta sẽ phải tự mình viết rất nhiều code, đặc biệt là JavaScript để render các thẻ HTML và điền nội dung theo yêu cầu.
Chúng ta sẽ không thể cập nhật các Server Control với Callback. Thí dụ chúng ta không thể fill data vào đối tượng GridView và render nó sau khi Callback. Để làm được điều giống như Postback, chúng ta sẽ viết JavaScript để sinh ra các thẻ <table><th><tr>… và fill dữ liệu sau khi Callback vào các vị trí tương ứng. Đây có thể nói là một công việc hết sức khổ ải vì chúng ta không tận dụng được lợi thế của các Web Control có sẵn có thể giúp render ra HTML Markup dễ dàng hơn rất nhiều.

Thiết kế định hướng Callback giúp trang Web nạp nhanh hơn so với Postback?
Không chính xác. Callback và Postback không xảy ra tại thời điểm ban đầu nạp trang. Postback và Callback xảy ra tại thời điểm khi có một yêu cầu gửi đến server tại thời gian thực (sau khi trang đã được nạp và sẵn sàng). Tại thời điểm gửi yêu cầu và phản hồi lại phía Client, Postback sẽ refresh lại toàn bộ trang (hoặc một vùng nào đó) do đó performance sẽ thấp hơn so với Callback (không vẽ lại bất cứ vùng nào trên trang). Như vậy nếu người dùng gửi yêu cầu không liên quan đến cập nhật UI từ server, thì có thể dùng Callback sẽ cho hiệu quả cao hơn so với Postback. Có thể nói về mức độ an toàn thì Callback có mức an toàn cao hơn vì yêu cầu gửi đi được thực hiện vòng (async) mà không thay đổi lại toàn bộ cấu trúc cây điều khiển của trang (Page Control Tree).

Chúng ta có thể sử dụng Callback khi thiết kế tính năng Download, kiểm tra sự tồn tại của một dữ liệu (thí dụ username), bình chọn (rate/vote), hoặc tự động nạp dữ liệu vào một số trường nào đó. Trong trường hợp này thì Callback có hiệu quả hơn hẳn so với Postback.



Callback  và Partial Postback trong Ajax khác nhau như thế nào?
AJAX là viết tắt của Asynchronous JavaScript and XML. Ajax có thể hiểu là công nghệ được hình thành bởi một tập hợp các các kỹ thuật phát triển Web, trong đó có Callback, để tạo nên các trang Web sinh động. Ajax là sự kết hợp cả JavaScript và XML, JSon.. để làm tối đa hóa công việc viết mã của các nhà lập trình Ajax.

Partial Postback là một kỹ thuật nằm giữa Callback (kỹ thuật thô sơ nhất) và Postback. Partial Postback trong Ajax sử dụng cơ chế Callback để phát động cuộc gọi lên server và cũng thực hiện các ASP.NET LifeCycle như một postback thông thường. Tuy nhiên Ạjax chỉ điều khiển quá trình rendering trên các control thay vì rendering lại toàn bộ trang Web. Ajax đóng gói các dữ liệu đã được render và gửi ngược trở lại Client. Về phía trình duyệt, Ajax cập nhật DOM cho trang Web với các thay đổi cần thiết.

Partial Postback không được hỗ trợ trong ASP.NET 2.0 (trong khi Callback đã có trong phiên bản này). Tuy nhiên AJAX đã giúp các nhà phát triển Microsoft làm điều này bằng cách bổ sung các thư viện hỗ trợ cho Partial Postback.

Như vậy Callback chỉ là một kỹ thuật nhỏ lẻ, cấp thấp và có lợi thế hơn Ajax trong việc khai thác các tính năng nhỏ để tăng mức User Experience cho trang Web.

Khi nào thì quyết định sử dụng Callback hoặc Postback?
Như đã nói ở trên, Callback đem lại sự thuận tiện cho người dùng khi phải vẽ lại toàn màn hình. Các developer thường hay mắc một nhược điểm là lạm dụng kỹ thuật Callback hoặc đối tượng UpdateManager quá nhiều sẽ khiến cho trang Web load chậm và hiệu quả cũng trở nên phản tác dụng khi hiện tượng co giật vẫn xảy ra do quá nhiều xung đột phát sinh. Do vậy tác giả đề nghị các developer cần hết sức lưu ý 2 nguyên tắc sau:
-  Chỉ sử dụng Callback đối với các action đơn giản, thí dụ rate một bài báo hoặc like một cái gì đó.
-  Đối với các action phức tạp như lưu dữ liệu, nên thiết kế full postback nhằm mục đích an toàn và hạn chế lỗi. Các developer cũng cần estimate xem một action xảy ra sẽ khiến trang Web thay đổi nhiều hay ít, nếu là thay đổi nhiều thì việc khai thác Ajax không đem lại hiệu quả nhiều, thay vào đó full postback là giải pháp tốt nhất.
 

Trong ASP.NET 2.0, các control như TreeView sử dụng rất nhiều script callbacks để thiết kế các tính năng expand/collapse. Trong khi đó GridView sử dụng callback để phân trang và sort dữ liệu mà không gây ra Postback.

    <asp:GridView ID="GridView1"
        DataSourceID="TitlesSource"
        EnableSortingAndPagingCallbacks="true"
        AllowPaging="true"
        AllowSorting="true"
        Runat="Server" />

Hi vọng bài viết này sẽ đem lại lợi ích cho những ai còn đang băn khoăn sẽ thiết kế trang Web theo hướng nào: Postback, Callback hay Ajax.

Happy Coding