最近在研究用AS3 Socket + AFM3 + C# Socket做通信
目前连接,发送消息一切都正常,就是当flex端将压缩后的二进制数据发送到服务端时不知道改如何将解压缩后的AsObject对象转化成特定的C#实体类.代码说明如下
flex端无异常private function onConnect( event:Event ):void {
    //连上服务端后压缩单体对象发送到服务端
    textField.text = "已连接上服务器,下面发送消息..."; 
    var param: Object = {Id: '1', Name: '赵果', Address: '中国浙江'};
    var _bytes:ByteArray = new ByteArray();
    _bytes.writeObject(param);
    _bytes.compress();
    socket.writeBytes(_bytes);
    socket.flush();
}private function onData( event:ProgressEvent ):void {
    //接收到服务端的消息解压缩后内容也能正常显示
    var _bytes:ByteArray = new ByteArray();
    while(socket.bytesAvailable > 0){
        socket.readBytes(_bytes);
    }
    _bytes.uncompress();
    var tmp:Object = _bytes.readObject();
    textField.text = tmp.Id + ',' + tmp.Name + ',' + tmp.Address; 
}
问题出在服务端private void onReceive(ICourageService server, object target)
{
    .......
    SocketAsyncEventArgs _eventArgs = target as SocketAsyncEventArgs;
    byte[] _bytes = _eventArgs.Buffer;//服务端接收到的二进制数据
    //利用FluorineFx组件实现ByteArray解压缩
    MemoryStream ms = new MemoryStream(_bytes, 0, _eventArgs.BytesTransferred);
    FluorineFx.AMF3.ByteArray ba = new FluorineFx.AMF3.ByteArray(ms);
    ba.Uncompress();
    STCServer.Node node = (STCServer.Node)ba.ReadObject();//问题就出在这里,运行到此行报错说无法将AsObject对象强制转换成Node类对象
    ......
}namespace STCServer
{
    public class Node
    {
        public uint ID;
        public string Name;
        public string Address;
    }
}
问题大概就是这样,找了好久都不知道如何才能将AFM3解析出来的AsObject()转换成C#中的实体类STCServer.Node,希望有遇到过相同问题的高手帮忙解决下啊,在线等!

解决方案 »

  1.   

    ba.ReadObject();跟踪一下这个返回的对象有哪些属性,这个对象跟你定义的node类没关系怎么能强转呢?
    把ba.ReadObject()中对应的属性值付给node类也行。
      

  2.   

    ba.ReadObject()里跟踪了没属性,从flex端压缩后发送到服务端来后,服务端再解压缩出来的一个AsObject类型对象.我就是想问怎么将这个AsObject类型的对象转换为C#实体类,应该需要一步类型映射的过程.
      

  3.   

    搞定了哈哈
    这里把解决办法帖一下好了
         MemoryStream ms = new MemoryStream(_bytes, 0, _eventArgs.BytesTransferred);
        FluorineFx.AMF3.ByteArray ba = new FluorineFx.AMF3.ByteArray(ms);
        ba.Uncompress();
        ASObject obj = (ASObject)ba.ReadObject();//关键在此,AsObject本身原来是一个Hash表,所以直接用Key,Value的形式读取就行了,不必转换成实体类,虽然这个做法不太严谨,不过也挺省事的嘿嘿~`
        string str = obj["Id"].ToString() + "," + obj["Name"].ToString() + "," + obj["Address"].ToString()只有一个朋友顶那分全给二楼的朋友好了哈哈
      

  4.   

    问一下我在这一步的时候就错了
    FluorineFx.AMF3.ByteArray ba = new FluorineFx.AMF3.ByteArray(ms);"FluorineFx.IO.AMFReader" 的类型初始化设定项引发异常用的官方的例子出现的,请问怎么解决
      

  5.   

    不是 obj[1]obj[0] 是
    string s = obj["updatetime"].ToString();
    是返回的 Result 里面的键值对 里的“键”
      

  6.   

    FluorineFx.ASObject result = (FluorineFx.ASObject)call.Result;
    string s = result["updatetime"].ToString();
      

  7.   


        public static class AmfEntityConvert
        {
            delegate object ConvertAction(object data);
            static Dictionary<Type, ConvertAction> dicTypeRelation = new Dictionary<Type, ConvertAction>();
            static AmfEntityConvert()
            {
                dicTypeRelation[typeof(FluorineFx.AMF3.ByteArray)] = new ConvertAction((object data) =>
                {
                    byte[] bytes = null;
                    if (data != null)
                    {
                        bytes = (data as FluorineFx.AMF3.ByteArray).GetBuffer();
                    }
                    return bytes;
                });
            }        public static T ConvertObject<T>(object asObject)
            {
                if (asObject != null)
                {
                    Type type = asObject.GetType();
                    if (dicTypeRelation.Keys.Contains(type))
                    {
                        return (T)dicTypeRelation[type](asObject);
                    }
                    else
                    {
                        return (T)Convert.ChangeType(asObject, typeof(T));
                    }
                }
                return default(T);
            }        public static object ConvertData(Type type, object obj, params object[] pams)
            {
                Type classType = typeof(AmfEntityConvert);
                MethodInfo staticMethod = classType.GetMethod("ConvertObject");
                MethodInfo genericMethod = staticMethod.MakeGenericMethod(type);
                return genericMethod.Invoke(obj, pams);
            }        /// <summary>
            /// 转换ASObject对象为.Net类型对象
            /// </summary>
            /// <param name="pObj"></param>
            /// <param name="type"></param>
            /// <returns></returns>
            public static object ConvertEntity(ASObject asObjeect, Type type)
            {
                try
                {
                    var tempObj = Activator.CreateInstance(type);
                    foreach (var asObj in asObjeect)
                    {
                        string key = asObj.Key;
                        object value = asObj.Value;                    MemberInfo[] members = type.GetMember(key);
                        if (null != value && members != null && members.Length > 0)
                        {
                            object newValue = null;
                            Type asValueType = asObj.Value.GetType();                        //.Net类型实体成员
                            MemberInfo member = members[0];
                            Type memberType = null;
                            FieldInfo field = null;
                            PropertyInfo property = null;
                            if (member.MemberType == MemberTypes.Field)
                            {
                                field = type.GetField(member.Name);
                                memberType = field.FieldType;
                            }
                            if (member.MemberType == MemberTypes.Property)
                            {
                                property = type.GetProperty(member.Name);
                                memberType = property.PropertyType;
                            }                        if (property != null || field != null)
                            {
                                //如果是ASObject对象
                                if (asValueType == typeof(ASObject))
                                {
                                    newValue = ConvertEntity((ASObject)value, memberType);
                                }
                                //如果是数组集合
                                else if (asValueType == typeof(Object[]))
                                {
                                    Type subtype = Assembly.GetAssembly(memberType).GetType(memberType.FullName.Replace("[]", ""), true);                                object[] arrobj = (Object[])value;
                                    var objData = Array.CreateInstance(subtype, arrobj.Length);
                                    for (int nn = 0; nn < arrobj.Length; nn++)
                                    {
                                        FluorineFx.ASObject asData = (FluorineFx.ASObject)arrobj[nn];                                    var val = ConvertEntity(asData, subtype);
                                        objData.SetValue(val, nn);
                                    }
                                    newValue = objData;
                                }
                                //基本类型
                                else
                                {
                                    newValue = ConvertData(memberType, null, value);
                                }                            if (field != null)
                                {
                                    field.SetValue(tempObj, Convert.ChangeType(newValue, memberType));
                                }
                                else if (property != null && property.CanWrite)
                                {
                                    property.SetValue(tempObj, Convert.ChangeType(newValue, memberType), null);
                                }
                            }
                        }
                    }
                    return tempObj;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
        }