原文地址:http://www.codeproject.com/aspnet/ajax_scribble.asp
源代码:http://www.codeproject.com/aspnet/ajax_scribble/ajax_scribble_src.zip
Atlas指南: 建立一个AJAX 涂鸦程序(二)
Global.asax
我们从Global.asax开始我们的编码过程。
1. 在 Website 菜单 点击 Add New Item 或者 Ctrl + Shift + A.
2. 在 Add New Item 对话框选择Global Application Class 并点击OK.你就可以看到已经创建了一个Global.asax文件了。
3. 导入 System.Drawing 名称空间. 在第一行下插入如下的代码。
<%@ Import Namespace="System.Drawing" %>
4. 在Session_Start 方法中增加如下代码.
void Session_Start(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(200, 200);
using (Graphics g = Graphics.FromImage(bmp))
{
g.FillRectangle(new SolidBrush(Color.White),
new Rectangle(0, 0, bmp.Width, bmp.Height));
g.Flush();
}
Session["Image"] = bmp;
}
这代码建立一个简单的bitmap 200*200像素白色,把整个背景绘制成白色的位图,并把它存储在名称为Image 的变量中。
5. Session_End 函数应该销毁存储在Session中的Image对象。
Bitmap bmp = (Bitmap)Session["Image"];
bmp.Dispose();
6. 从 Website 菜单选择 Add Reference.
7. 选择 System.Drawing 在 Add Reference 对话框并点击OK
8. 最后,在Build 菜单点击Build Web Site 或者按下 Ctrl + Shift + B 确保 没有任何编译错误。
ScribbleImage.ashx
该web处理器假定把存储在session中的image对象流回到客户端。
- 在 WebSite 菜单点击 Add New Item 或者按下 Ctrl + Shift + A.
- 在 Add New Item对话框选择Generic Handler, 把handler的名称改为ScribbleImage.ashx 并点击OK.
- 为了让一个web handler使用session变量,它需要实现接口IRequiresSessionState. 这只是一个标记性接口,没有任何方法。
public class ScribbleImage : IHttpHandler,
System.Web.SessionState.IRequiresSessionState
- 接下来我们向 ProcessRequest 方法中添加代码.
public void ProcessRequest (HttpContext context)
{
context.Response.ContentType = "image/png";
context.Response.Cache.SetNoStore();
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetExpires(DateTime.Now);
context.Response.Cache.SetValidUntilExpires(false);
System.Drawing.Bitmap bmp =
(System.Drawing.Bitmap)context.Session["Image"];
lock(bmp)
{
using (MemoryStream ms = new MemoryStream())
{
bmp.Save(ms, ImageFormat.Png);
ms.Flush();
context.Response.BinaryWrite(ms.GetBuffer());
}
}
}
}
- 第一行设置 ContentType header in the response to image/png. 这确保浏览器识别响应是一个png image而不是HTML.
- 接下来的四行指示浏览器,该响应不需要缓存。这四行是必需的,保证了代码跨浏览器兼容。我们将在指南的后续版本中优化这些代码。
- 最后,从session变量中来的bitmap被保存在内存流中(memory stream),并且内存流中的内容被写向响应。BinaryWrite 函数被使用,因为image是二进制数据。
ScribbleService.asmx
我们已经对初始化session image和把image内容流向响应(response)有一定了解了,现在我们需要某个方法把内容加入image对象自己。我们期望客户端调用ScribbleService.asmx web服务把lines加入image。
- 在 WebSite 菜单点击Add New Item 或者按下Ctrl + Shift + A.
- 在Add New Item对话框选择Web Service, 确认名称为ScribbleService.asmx 并点击OK.确保你没有选择Place Code in a Separate File.
- 导入名称空间 System.Drawing 。
using System.Drawing;
4. 接下来,我们需要为point定义一个简单的类。我们不能使用System.Drawing.Point 类因为它不能XML序列化。在以后的指南中我们将看到如何用System.Drawing.Point 代替自定义的类。在定义ScribbleService 类之前,我们加入下面的代码:
public class Point
{
public int X;
public int Y;
}
5. 最后, 我们需要增加一个方法来根据给定的一些点绘制草图。我们增一个Draw web 方法: [WebMethod(EnableSession = true)]
public void Draw(Point[] points)
{
Image scribbleImage = (Image)Session["Image"];
lock(scribbleImage)
{
using (Graphics g = Graphics.FromImage(scribbleImage))
using(Pen p = new Pen(Color.Black, 2))
{
if (points.Length > 1)
{
int startX = points[0].X;
int startY = points[0].Y;
for (long i = 1; i < points.Length; i++)
{
g.DrawLine(p, startX, startY,
points[i].X, points[i].Y);
startX = points[i].X;
startY = points[i].Y;
}
}
}
}
}
- 特性(attribute) WebMethod(EnableSession = true) 确保从web服务能访问session变量。
- Image被锁定确保并发访问是安全的
- 绘制它自己是相当简单的,就是把points 数组中的点连接起来.
本想一次发完,但就是发不成功,郁闷!! 未完!!