如何在flex中为c#后端序列化对象

如何在flex中为c#后端序列化对象,c#,apache-flex,actionscript-3,web-services,serialization,C#,Apache Flex,Actionscript 3,Web Services,Serialization,我们正在开发一款具有Flex前端和C#后端的应用程序,通过web服务连接。 我们使用FlexBuilder3的Web服务管理器自动生成Web服务类。 当Flex序列化我们的对象时,问题就出现了,例如,当我们有一个没有值的Number属性时,它被序列化为NaN,而我们的后端不知道NaN。另一个例子是当我们序列化一个循环引用时,我们得到一个堆栈溢出异常。 例如,我知道在java中,您可以配置xstream使用循环引用的工作方式。。。所以,问题是,我们能否改变Flex序列化对象的方式,使C#能够使用这

我们正在开发一款具有Flex前端和C#后端的应用程序,通过web服务连接。 我们使用FlexBuilder3的Web服务管理器自动生成Web服务类。 当Flex序列化我们的对象时,问题就出现了,例如,当我们有一个没有值的Number属性时,它被序列化为NaN,而我们的后端不知道NaN。另一个例子是当我们序列化一个循环引用时,我们得到一个堆栈溢出异常。 例如,我知道在java中,您可以配置xstream使用循环引用的工作方式。。。所以,问题是,我们能否改变Flex序列化对象的方式,使C#能够使用这个前端?关于flex如何序列化对象,我们应该知道哪些问题? 谢谢
Jorge

据我所知,当您使用Flex Bluider的Web服务管理器时,会为您创建的每个Web服务自动生成代理操作脚本类。序列化过程在访问某个Web服务时使用这些类。您可以编辑这些类的属性,以便它们始终可以在C#端进行处理(这样就可以去掉NaN值)


我看到的另一个选择是编写自己的自定义代码来处理XML和XML之间的对象。我不知道如何更改自动生成类的序列化,但我将尝试提供以下帮助:

您可能在寻找什么(尽管我从未使用过此功能,但我一直看到有人提到它):

我所做的事情:

  • 使用JSON,这可以很容易地用
另一个我从未尝试过的想法:

  • 与Actionscript插件一起使用
关于你面临的问题:

  • 我在将对象序列化到Java时遇到了很多问题,所以请彻底测试
  • 我尝试在.Net中使用自动生成的web服务,它也有序列化问题。在更新SDK时,自动生成似乎发生了很大的变化,但我的服务仍然不走运,也没有找到根本原因

我想你应该考虑一下不同的设计,我们也有类似的问题,但是我们开发了以下的解决方案。 仅原语参数

// I will only define the fields I want to pass to server
// this needs to be done at backend level
class PersonAddressWrapper{
    long PersonAddressID;
    string AddressLine1;
    string AddressLine2;
    string ZipCode;
    string City;
    string Country;
}

class PersonWrapper{
    long PersonID;
    string Name;
    PersonAddressWrapper[] Addresses; 
}

[WebMethod]
public void SavePerson(PersonWrapper pw){
    Person p = GetPersonByID(pw.PersonID);
    p.Name = pw.Name;
    p.Save();
    foreach(PersonAddressWrapper paw in pw.Addresses){
        PersonAddress pa = GetPersonAddressByID(paw.PersonAddressID);
        Copy(pa,paw);
        pa.Save();
    }
}
仅在Web服务方法参数(字符串、int)等中定义基元类型

比如你有一门课

class Person{
    long PersonID;
    long MembershipID;
    string Name;
}
你只想改变后端的“Name”属性,事实是,你不应该信任你的前端,你应该认为前端很容易被破坏,并且可以发送错误的数据,比如在这种情况下,MembershipID是前端永远不能修改的字段

您可以编写自己的代码,让他人正确保存,但有人很容易读取WSDL并破坏代码

所以不是这个

[WebMethod] 
public void SavePerson(Person p){
    p.Save(); <-- this is dangerous
}
我知道很多人会争辩说,这将导致更多的编码以及到服务器的更多往返,然而,通过使用专门的包装器类也可以避免往返

在参数中使用包装类

// I will only define the fields I want to pass to server
// this needs to be done at backend level
class PersonAddressWrapper{
    long PersonAddressID;
    string AddressLine1;
    string AddressLine2;
    string ZipCode;
    string City;
    string Country;
}

class PersonWrapper{
    long PersonID;
    string Name;
    PersonAddressWrapper[] Addresses; 
}

[WebMethod]
public void SavePerson(PersonWrapper pw){
    Person p = GetPersonByID(pw.PersonID);
    p.Name = pw.Name;
    p.Save();
    foreach(PersonAddressWrapper paw in pw.Addresses){
        PersonAddress pa = GetPersonAddressByID(paw.PersonAddressID);
        Copy(pa,paw);
        pa.Save();
    }
}
通过这种方式,您可以减少往返,还可以组织包装器类以包含/排除可以删除循环依赖项及其安全性的项


是的,我知道这需要更多的工作,但这是安全的方法。

也许我已经找到了解决您问题的方法

如果在FlexBuilder3中使用自动生成的类,则可以捕获并修改传出的soap消息。在“Base[ServiceName]”类的“call()”函数中很容易做到这一点

您需要做的就是在字符串之前修改“soap”变量

message.body = soap.toString();
在我的例子中,我创建了cleanXML函数(见下文)。此函数删除所有等于“NaN”或具有xsi:nil='true'属性的XML元素

private function cleanXML(xml:XML, qn:QName):void{
    if (XMLList(xml).hasSimpleContent()){
        if ((xml.valueOf() == "NaN") || (xml.attribute(qn) == true)){
            delete xml.parent().children()[xml.childIndex()];
        }
    }else{      
        for each (var item:XML in xml.children()){
            cleanXML(item, qn);
        }   
    }
} 
因此,call()函数中提到的部分是:

    var soapList:XML;
    soapList = soap as XML;

    var qn:QName = new QName(soapList.namespace("xsi"), "nil");
    cleanXML(soapList, qn);         

    message.body = soapList.toString();
我知道这个决定是不好的,因为在我的情况下,它是完美的