flex与.Net的HTTPSerivce通信

来源:互联网 发布:什么叫大数据分析 编辑:程序博客网 时间:2024/05/01 09:21
在adobe官网的一篇文章(http://www.adobe.com/devnet/flex/articles/communicating_flex_dotnet.html)很详细地讲解了.net和flex的几种通信方式。下面我分析一下重点部分
PS:完整的代码可到上面的网址下载

1.数据结构的对应
这个程序分别用ClassData和StudentData两个类来代表班级和学生。flex和.Net都有自己的数据类型。我们看看如何声明这两个类让他们对应起来。

首先是StudentData.cs
namespace FlexToNet.Data
{
    public class StudentData
    {
        public int StudentID;
        public string StudentName;
    }
}
然后是StudentData.as
package
{
    [RemoteClass(alias="FlexToNet.Data.StudentData")]//这个可以省略,只是原例子在remote通信要用到
    public class StudentData
    {
        public function StudentData()
        {
           
        }
       
        public var StudentName:String;
        public var StudentID:int;
    }
}
事实上StudentData的声明很简单,只要字段名和字段类型对应即可。

再看看复杂一点的ClassData.cs
using System.Collections.Generic;

namespace FlexToNet.Data
{
    public class ClassData
    {
        public string ClassName;
        public string TeacherName;
        public int TeacherID;
        public List<StudentData> Students;
    }
}

以及ClassData.as
package
{
    import mx.collections.ArrayCollection;
   
    [RemoteClass(alias="FlexToNet.Data.ClassData")]
    public class ClassData
    {       
        public var ClassName:String;
        public var TeacherName:String;
        public var TeacherID:int;
       
        private var _students:ArrayCollection;
       
        public function ClassData()
        {
           
        }

        [Bindable]
        public function set Students(value:ArrayCollection):void
        {
            _students = value;
        }
       
        public function get Students():ArrayCollection
        {
            return _students;
        }
    }
}
ClassData.as中说明ArrayCollection与C#的List是对应的。它也展示了如何使用一个private变量和get/Set属性(注意get set中间有空格,所以不是普通函数)。至于[Bindable]标签是为了保证_students被修改了以后,界面可以马上反应出来。



2.HTTPService
定义好数据类型后,我们就要进行两者的通信。
HTTPService可以利用静态或者动态两种方法。
静态就是flex直接download服务器上一份Xml文件,直接对其解析获取数据。
动态原理就是由flex访问服务器的aspx页面,而aspx页面利用XmlSerializer类将要传输的数据变成XML返回给flex进行解析。下面的例子演示了如何动态产生Xml数据。

首先是flex的核心部分代码:
这里要定义HTTPService,包括aspx页面的地址,处理函数等
<mx:HTTPService id="httpService"                                                            
url="http://localhost/HttpService/RosterXMLService.ashx" //页面地址
result="httpServiceResultHandler(event)" //在获得结果之后用什么函数处理
resultFormat="e4x" >//指定了返回的数据会被翻译成actionscript3.0能够理解的内容
<mx:request xmlns="">
<numStudents>//定义请求的具体内容
{studentStepper.value}//studentStepper是一个界面元素,这里忽略了相关代码
</numStudents>
</mx:request>
</mx:HTTPService>

然后是实现处理函数,处理接收到的信息
private function callHttpService():void {//这个函数会和发送按钮的click事件绑定
httpService.send();
}
private function httpServiceResultHandler(event:ResultEvent):void {//处理结果
var classResult:XML = event.result as XML
// Alternatively this would achieve the same effect
// var classResult:XML = httpService.lastResult as XML;
//Set up ClassData object
var classData:ClassData = new ClassData();
classData.ClassName = classResult.ClassName;
classData.TeacherName = classResult.TeacherName;
classData.TeacherID = classResult.TeacherID;
classData.Students = new ArrayCollection();
for each(var student:XML in classResult.Students.StudentData) {
var studentData:StudentData = new StudentData();
studentData.StudentName = student.StudentName;
studentData.StudentID = student.StudentID;
classData.Students.addItem(studentData);
}
//Update the UI to display the class data
updateUI(classData);
}
其中callHttpService是用于发送请求的,在例子中它可以直接成为“发送”按钮的处理函数
可以看到httpServiceResultHandler很简单地把event.result转为XML,然后解析内容就可以了

最后看看aspx页面如何响应flex的请求
rosterClickXmlService.ashx
<%@ WebHandler Language="C#" Class="RosterXmlService" %>

using System;
using System.Collections.Generic;
using System.Web;
using System.Xml.Serialization;
using FlexToNet.Data;

public class RosterXmlService : IHttpHandler {

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";

        ClassData sampleClass = new ClassData();
        sampleClass.TeacherID = 10;
        sampleClass.TeacherName = "Smith";
        sampleClass.ClassName = "Science";
        sampleClass.Students = new List<StudentData>();

        int numStudents = Int32.Parse(context.Request.Params["numStudents"]);

        for (int i = 0; i < numStudents; i++)
        {
            StudentData student = new StudentData();
            student.StudentID = i + 1;

            if (i % 2 == 0)
            {
                student.StudentName = "Denis";
            }
            else
            {
                student.StudentName = "Alexey";
            }
            sampleClass.Students.Add(student);
        }

        XmlSerializer ser = new XmlSerializer(typeof(ClassData));//产生Xml数据
        ser.Serialize(context.Response.Output, sampleClass);
    }

    public bool IsReusable
    {
        get
        {
            return true;
        }
    }

}

事实上去除了逻辑部分的代码之后就很简单了。主要就是首先让这个类实现IHttpHandler接口,然后利用XmlSerializer生成Xml数据,再通过context.Responce.Output发送出去。