2010年6月3日星期四

jQuery Ajax配WebService的以外選擇 - Ashx

jQuery用Post方式去呼叫Web Service是最常見的運作方式,不過jQuery除了.post(),還有.get() / .load() / .getScript().getJSON()都是常用的方法。

有點不同的是,後四者一般使用上都是想直接取得字串資料居多,甚至只是單單True或False。(可參考jQuery的Demo)
故然若以最低成本為大前題,使用WebService就不太恰當。
甚至有時候會用Javascript for...loop 去循環callback的話,低成本,快速的程序更為重要。
所以我們便需要用上Ashx。

Ashx只是Extension名,而Ashx正式名稱是Generic handler。
或者可能會問,為什麼不用aspx的response.write去做?
其實的確用response.write是可以做到同一效果,但*.ashx和*.aspx有少少不同:
  1. ashx可以return binary file,例如Image,Zip etc...
  2. ashx並不需要經過aspx的Page Cycle,例如Page_Init , Page_Load etc...
  3. ashx可以在web.config設定http request的處理方式

特別是第二,三點,所以以速度來說,ashx是比aspx更快,更省CPU資源。

以下是ashx示範,是由MSSQL取得 Image Field 並呈現在瀏覽器上,如果文字處理就更簡單,Visual Studio的ashx文件,預設的就是Hello World示範。

<%@ WebHandler Language="VB" Class="ShowStudentImage" %>

Imports System
Imports System.IO
Imports System.Data
Imports System.Data.SqlClient
Imports System.Web

Public Class ShowStudentImage : Implements IHttpHandler
Dim StudentID As String = ""
Private Property SID() As String
Get
Return StudentID
End Get
Set(ByVal value As String)
StudentID = value
End Set
End Property

Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
If context.Request.QueryString("StudentID") IsNot Nothing Then
SID = context.Request.QueryString("StudentID")
Else
Throw New ArgumentException("No parameter specified")
End If

context.Response.ContentType = "image/jpeg"
Dim strm As Stream = ShowEmpImage(SID)
Dim buffer As Byte() = New Byte(4095) {}
Try
Dim byteSeq As Integer = strm.Read(buffer, 0, 4096)
While byteSeq > 0
context.Response.OutputStream.Write(buffer, 0, byteSeq)
byteSeq = strm.Read(buffer, 0, 4096)
End While
Catch
context.Response.ContentType = "image/gif"
context.Response.WriteFile("images/Transparent.gif")
End Try
End Sub

Public Function ShowEmpImage(ByVal StudentID As String) As Stream
Dim connection As New SqlConnection(ConfigurationManager.ConnectionStrings("ClientsConnectionString").ConnectionString)
connection.Open()
Dim sql As String = "SELECT Photo FROM Student WHERE StudentID = @SID"
Dim cmd As New SqlCommand(sql, connection)
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("@SID", Integer.Parse(StudentID))
Dim img As Object = cmd.ExecuteScalar()
Try
Return New MemoryStream(DirectCast(img, Byte()))
Catch
Return Nothing
Finally
connection.Close()
End Try
End Function

Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class

沒有留言:

發佈留言