Atlas教程:创建 AJAX Scribble应用程序

来源:互联网 发布:阿里云客服工资怎么算 编辑:程序博客网 时间:2024/05/17 06:42

Atlas教程:创建 AJAX Scribble应用程序

  • 下载 C# 源文件- 74 KB
  • 下载 VB.Net 源文件( 由 Hudson Akridge贡献) - 20 KB

请阅读文章末尾的说明,了解如何在下载源代码后运行应用程序。

。IE 中的图像。Firefox 中的图像

介绍

基于 ASP.NET Atlas 是一套丰富的客户端和服务器端库,开发使用 ASP.NET的AJAX-style应用。 本教程( 在这个系列中可能更多) 试图提供Atlas中可用特性的一般视图。 因为,Atlas是一个非常庞大的库,本教程主要介绍Atlas的两个最重要的功能:

  • 从客户端脚本调用服务器端 Web服务的能力
  • 易于开发 跨浏览器 兼容的JavaScript代码

背景

MFC Scribble应用程序是我用来学习MFC的第一个应用程序。 因此,我决定把这个教程基于 Scribble 。 Scribble应用程序允许用户使用鼠标徒手绘制草图。 我首先在web上看到类似的应用程序,利用AJAX技术,在网站上。 JavaScript绘图网站只在 Mozilla Firefox 上工作。 本文介绍如何构建应用程序的跨浏览器 版本。 我们将在 在本系列文章中的每一篇文章都展示了。

正在安装 Atlas

当时的本文编写之际,12月CTP的图谱可以通过单击这里 链接下载。 如果这里链接无效,你可以随时访问Atlas网站获得正确的链接。 Atlas库作为 Visual Studio 2005模板( VSI ) 可用。 下载站点有关于如何安装模板的说明。

创建Atlas项目

安装Atlas模板后,你可以通过单击菜单选项来创建一个空白的Atlas项目: 文件-> New -> 网站。 这将显示 New 网站对话框,如下所示。

Visual Studio Project

在位置上你可以选择文件系统或者 HTTP 。 选择HTTP将允许你在IIS服务器上创建网站,选择文件系统将允许你在本地文件系统( 你可以使用 ASP.NET 开发web服务器调试和测试) 上创建网站。 你可以选择任一选项,但我发现在IIS上使用 IE的应用程序。

Atlas空白项目

新创建的Atlas网站具有以下目录结构。

  • App_Data
    这是一个空目录,你可以在其中放置数据文件。

  • 这是放置程序集 Microsoft.Web.Atlas的dll文件的目录。 这包含了Atlas库的服务器部分。

  • 可以放置应用程序的任何JavaScript文件的目录。

    • Atlas客户端脚本位于以下两个不同的子目录中。
      • 调试
        Atlas客户端JavaScript文件的调试版本放在这个目录中。

      • Atlas客户端JavaScript文件的发布版本放在这个目录中。 这里目录中的脚本更紧凑,并且已经移除一些调试代码。

Atlas客户端脚本

Atlas的December版本有以下客户端脚本。

  • Atlas.js
    这是核心的Atlas脚本文件,由基本的实用函数和客户端控件和组件组成。
  • AtlasCompat.js
    这里文件包含支持 Mozilla Firefox 和Apple-iMac-Safari浏览器的Atlas兼容层。 这里脚本确保Atlas代码是 跨浏览器 兼容的。
  • AtlasCompat2.js
    这个文件包含了确保Safari浏览器兼容性的附加功能。
  • AtlasRuntime.js
    这是核心Atlas脚本文件的缩减版本。 这里脚本文件没有客户端组件和控件。 当不能在网页中使用上述组件或者控件时,可以使用这里脚本文件。
  • AtlasUIDragDrop.js
    这里文件包含用于在网页中提供拖放功能的实用工具函数。
  • AtlasUIGlitz.js
    这里文件包含用于在网页中提供动画和其他特效的实用函数。
  • AtlasUIMap.js
    这是使用虚拟地球的Atlas映射框架的脚本文件。

其他文件

Atlas将以下文件添加到网站的root 目录中。

  • Default.aspxDefault.aspx.cs
    这是一个包含Atlas脚本管理器控件的网页,负责绘制引用Atlas客户端端脚本的脚本块。 还向页面添加了类型为 test测试/xml-script 块的客户端脚本。 这里脚本块用于使用声明性的XML语法编写脚本。
  • eula.rtf
  • readme.txt
  • Web.Config
    于正在运行的相关图谱 applications, Web.Config essential.是 它包含一些特定于Atlas的配置设置,还添加了Atlas模块和HTTP处理程序。

Scribble应用程序"

Scribble应用程序允许用户通过单击鼠标左键并移动鼠标来绘制手绘草图。 当用户释放鼠标按钮或者在绘图区域外移动时,绘制笔触结束。 有一些方法可以使用javascript利用vml画,但我们不会使用vml在这个示例。

Scribble中的默认网页将有一个图像( 一个普通的HTML图像- IMG标签) 。 使用JavaScript事件处理程序捕获图像上的用户鼠标事件。 JavaScript函数将草图笔划中的一系列点发送到web服务。 web服务更新和图像对象通过绘制由客户端发送的所有点在会话变量中保存的图像对象。 finally,客户端从服务器请求更新的映像。 图像源是一个HTTP处理程序,它将会话变量中存储的图像流到客户端。 下面是应用程序的主要组件。

  • Default.aspx
    使用动态图像和Atlas脚本管理器控制页面。
  • ScribbleImage.ashx
    这是一个HTTP处理程序,它流入会话变量中存储的图像对象。
  • ScribbleService.asmx
    这是将所有草图请求发送到的网络服务。 web service修改图像。
  • Scribble.js
    应用程序的JavaScript代码驻留在这个文件中,以便在设计和代码之间明确分离。
  • Global.asax
    Session_Start and Session_End 事件 in基金会are Global.asax 。Session_Start 创建会话变量,Session_End 释放存储在会话变量中的映像。

Global.asax

我们从 Global.asax 开始编码过程。

  • 网站菜单单击 New 添加项或按 Ctrl + Shift +
  • New 添加项对话框中选择 全局应用程序类,然后单击确定。 你将看到创建的Global.asax 文件。
  • 首先导入 System.Drawing 命名空间。 在第一行之后插入下面一行代码。
<%@ Import Namespace="System.Drawing" %> 
  • 将以下代码添加到 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;} 
代码通过 200像素像素创建一个简单的位图 200像素,绘制整个背景白色,并将它的分配给名为 Image的会话变量。
  • Session_End 函数应处理存储在会话变量中的图像。
Bitmap bmp = (Bitmap)Session["Image"];bmp.Dispose();
  • 网站菜单选择添加引用。
  • 添加引用对话框中选择 System.Drawing,然后单击 OK
  • 最后,在构建 菜单中单击生成网站或者按 Ctrl + Shift + B 来确保没有构建错误。

ScribbleImage.ashx

这个网络处理程序应该将存储在会话变量中的图像流回客户端。

  • 网站菜单单击 New 添加项或按 Ctrl + Shift +
  • New 添加项对话框中选择泛型处理程序,将处理程序的名称设置为 ScribbleImage.ashx,然后单击确定。
  • 对于使用会话变量的web处理程序,它需要实现接口 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()); } } }}
  • 第一行在对图像/png的响应中设置 ContentType header 。 这确保浏览器将响应标识为png图像而不是 HTML 。
  • 接下来的四行向浏览器表明响应不应该被缓存。 所有这四行都是必需的,以确保代码是 跨浏览器 兼容。 我们将在教程的后面版本中优化代码。
  • 最后,将会话变量中的位图保存到内存流中,并将内存流的内容写入响应流。 使用 BinaryWrite 函数,因为图像是二进制数据。

ScribbleService.asmx

我们有初始化会话映像和将图像内容流作为响应的方法。 现在我们需要一些方法来向图像本身添加内容。 我们期望客户端在 ScribbleService.asmx web服务上调用image添加行。

  • 网站菜单单击 New 添加项或按 Ctrl + Shift +
  • New 项添加对话框选择 web服务,指定名字 ScribbleService.asmx 并单击ok。 确保你在单独的文件中取消了位代码。
  • 通过向命名空间导入系列添加以下行来导入命名空间 System.Drawing 。
using System.Drawing;
  • 接下来,我们需要为点定义一个简单的类。 不能使用 System.Drawing.Point 类,因为它不是XML序列化的。 在后面的教程中,我们将看到如何使用System.Drawing.Point 而不是定制类。 在 ScribbleService 类声明之前添加下面的代码
public class Point{ public int X; public int Y;}; 
  • 最后,我们需要添加一个方法来绘制给定点的草图。 我们将web方法 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; } } } }}
  • 属性 WebMethod(EnableSession = true) 确保可以从web服务访问会话变量。
  • 图像被锁定以确保并发访问安全。
  • 图形本身非常简单,因为它只连接 points 数组中提供的点。

Scribble.js

我们有服务器端图像处理程序和服务器端web服务来更新映像。 现在我们需要scribble应用程序中的客户端脚本,它将鼠标事件从鼠标事件发送到服务器web服务。

  • 在解决方案资源管理器中突出显示 文件夹。
  • 网站菜单单击 New 添加项或按 Ctrl + Shift +
  • In New Add 。 项目精选的jscript po box dialog牵头,sepcify,以 and Scribble.js"信息通信业明智地结合。 This will placeScribble.js in ScriptLibrary folder.
  • 接下来我们需要声明一些全局变量。 在scribble的第一个版本中,我们将使用全局变量,但是在接下来的版本中我们开始使用JavaScript对象。
//The HTML image element that is to be drawnvar image;//The source of the imagevar originalSrc;//The number of iterationvar iter = 0;//The array of pointsvar points = null;
变量声明上面的注释描述了每个变量背后的用途。 在将draw请求发送到服务器后,iter 变量用于修改映像的源。 如果 IE 设置为 image.src = image.src,则刷新图像,但相同的代码不能用于 Firefox 。 为了解决这个问题,我们维护每次向web服务发送 Draw 请求时增加的变量 iter 。 我们将迭代号添加到 originalSrc 变量,以便浏览器认为它需要请求服务器获取新数据,而不是使用缓存的图像。
  • 我们定义了函数 startStroke,它开始响应 mousedown 事件。
function startStroke(){ points = new Array(); window.event.returnValue = false;}
当 new 笔画开始时,我们创建一组新的点,如第一行所示。 第二行取消事件的默认行为。 这是必须的,因为图像的mousedown事件的默认行为是开始一个拖动操作,阻止任何进一步的事件被触发。
  • 当中风以响应 mouseup 事件或者 mouseout 事件结束时,我们需要对web服务进行实际调用。 这是在endStroke 函数中完成的。
function endStroke(){ if (!points || points.length <2) return true; //Send the points to the webservice ScribbleService.Draw(points, onWebMethodComplete, onWebMethodTimeout, onWebMethodError); points = null; window.event.returnValue = false;}
函数中唯一有趣的行是 ScribbleService.Draw(points, onWebMethodComplete, onWebMethodTimeout, onWebMethodError); ,它在ScribbleService.asmx 异步调用web服务方法 Draw 。 功能由Atlas框架自动提供给我们。
  • 当web服务方法发生错误时,onWebMethodError 是一个函数,当web方法调用超过了Atlas框架中定义的可以配置超时时,onWebMethodTimeout 就会被调用。 在这个版本中,我们只向用户显示一个带有错误文本的消息框。
function onWebMethodError(fault){ alert("Error occured:n" + fault.get_message());}function onWebMethodTimeout(){ alert("Timeout occured");}
  • 当web方法调用成功时调用 onWebMethodComplete 函数。 当发生这种情况时,需要重新加载映像。
function onWebMethodComplete(result, response, context){ //We need to refresh the image var shimImage = new Image(200, 200); shimImage.src = originalSrc + "?" + iter++; shimImage.onload = function() { image.src = shimImage.src; }}

我们创建一个 Image 对象 shimImage 并将它的源设置为我们正在绘制的图像的原始源。 当图像对象加载时,我们将页面上实际的HTML图像元素的源设置到临时图像对象的源。 这样做是为了避免在替换图像时闪烁。
  • 我们需要在 mousemove 事件中填充 points 数组。 这是在 addPoints 函数中完成的。
function addPoints(){ if (points) { var point = { X : window.event.offsetX, Y : window.event.offsetY}; points.push(point); if (points.length == 3) { endStroke(); points = new Array();  points.push(point); } window.event.returnValue = false; }}
  • 使用事件对象的offsetXoffsetY 属性构造 new 点对象,然后将它的附加到 points 数组。 offsetXoffsetY 属性相对于导致事件的HTML元素给出相对鼠标位置。
  • 如果数组长度达到 3,我们会自动请求服务器执行绘制操作并重置 points 数组。 这样做的目的是让用户在释放鼠标按钮之前可以看到图形。
  • 最后,我们需要将在 pageLoad 函数中完成的事件钩子。
function pageLoad(){ var surface = document.getElementById("drawingSurface"); image = surface.getElementsByTagName("IMG")[0]; originalSrc = image.src; surface.attachEvent("onmousedown", startStroke); surface.attachEvent("onmouseup", endStroke); surface.attachEvent("onmouseout", endStroke); surface.attachEvent("onmousemove", addPoints);}
  • pageLoad 函数是在Atlas框架完成加载时调用的特殊函数。 我们使用这个代替常规的窗口或者身体加载事件,这样我们就可以确保Atlas已经完成加载。
  • 将绘制的实际图像元素放置在 div 标记内,并带有 drawingSurface的id 。 元素的大小与图像的大小相同,因此我们可以安全地将事件附加到drawingSurface div 。

Default.aspx

应用程序的各个组件需要在 Default.aspx 页面中组装。 下面是这个页面的代码。

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"    Inherits="_Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title>Atlas Scribble Sample</title></head><body> <form id="form1" runat="server"> <Atlas:ScriptManager ID="AtlasScriptManager" runat="server"            EnableScriptComponents="False" > <Services> <Atlas:ServiceReference Path="ScribbleService.asmx" /> </Services> <Scripts> <Atlas:ScriptReference Path="ScriptLibrary/Scribble.js" /> </Scripts> </Atlas:ScriptManager> <div id="drawingSurface"            style="border:solid 1px black;height:200px;width:200px"> <img alt="Scribble" src="ScribbleImage.ashx"            style="height:200px;width:200px" galleryimg="false" /> </div> </form></body></html>

这里页面最重要的方面是 atlas:ScriptManager 服务器控件。 ScriptManager 服务器控件负责为Atlas和任何web服务代理脚本生成客户端脚本块。 让我们在Default.aspx 页面中检查 ScriptManager 控件的用法。

  • EnableScriptComponents 属性设置为 false 。 这生成一个客户端脚本块指 AtlasRuntime.js 代替Atlas.js 。 我们更喜欢这个版本的Atlas框架的轻量级版本,因为我们不使用任何Atlas组件或者控件。
  • 我们将服务引用添加到 ScribbleService.asmx web服务。 这将为web服务代理生成客户端脚本的URL引用。
  • 我们将 Scribble.js 作为另一个脚本引用添加。

这将把所有的Fragment一起组装起来,现在你可以编译和运行这个项目了。 我鼓励你查看由Atlas脚本管理器生成的实际客户端 html 。


原创粉丝点击