flash.utils.IExternalizable + Remoting + Flex Ошибка # 2004 - PullRequest
0 голосов
/ 05 февраля 2012

Есть базовое приложение клиент-сервер. Клиент использует простое удаленное взаимодействие для связи со стороной сервера. На стороне сервера может работать WebORB, BlazeDS или любой другой продукт. Клиентская сторона использует инфраструктуру FLEX. Вот и все о стеке технологий. Теперь давайте забудем о стороне сервера и просто взглянем на следующую клиентскую сторону

package com.blog.ri
{
    import mx.collections.ArrayCollection;

    public class MyCollection extends ArrayCollection
    {
        public function MyCollection(source:Array=null)
        {
            super(source);
        }
    }   
}

Кроме того, давайте предположим, что у нас есть следующий класс, и он сопоставлен с классом на стороне сервера:

package com.blog.ri
{
    [Bindable]
    [RemoteClass(alias="com.blog.ri.MyEntity")]
    public dynamic class MyEntity
    {   
        private var _myCollection:MyCollection;

        public function get myCollection():MyCollection
        {
            if(_myCollection == null)
                _myCollection = new MyCollection();

            return _myCollection;
        }

        public function set myCollection(value:MyCollection):void
        {
            _myCollection = value;
        }       
    }
}

Кроме того, служба на стороне сервера предоставляет клиентам метод void save (MyEntityандидат), и я реализовал его на стороне клиента, как показано ниже:

package com.blog.ri
{
    public class MyService
    {       
        private var _remoteObject:RemoteObject;

        public function MyService()
        {
            var channelSet:ChannelSet = new ChannelSet();
            var amfChannel:AMFChannel = new AMFChannel("my-amf", "http://localhost/weborb.aspx");
            channelSet.addChannel(amfChannel);

            _remoteObject  = new RemoteObject("GenericDestination");
            _remoteObject.channelSet = channelSet;
            _remoteObject.source = "com.blog.ri.MyService";
            _remoteObject.getDetailedStatistic.addEventListener("result",onItemSaved);
            _remoteObject.addEventListener("fault", onFault);
        }

        public function save(candidate:MyEntity, responder:IResponder = null ):void
        {
            var asyncToken:AsyncToken = _remoteObject.save(candidate);

            if( responder != null )
                asyncToken.addResponder( responder );
        }

    }
} 

Наконец, я попытался сохранить новый экземпляр класса MyEntity в нашем основном файле mxml, как показано ниже:

protected function creationCompleteHandler():void
            {
                var myService:MyService = new MyService();

                var candidate:MyEntity = new MyEntity();
                candidate.myCollection = new MyCollection();

                myService.save(candidate);
            }

Вот и все. Когда я запускаю код, я получил следующее исключение:

ArgumentError: Ошибка № 2004: один из параметров недопустим. в flash.net::NetConnection/invokeWithArgsArray () в flash.net::NetConnection/call () в mx.messaging.channels :: NetConnectionChannel / internalSend () [E: \ DEV \ hero_private \ рамки \ проекты \ RPC \ SRC \ тх \ сообщениями \ каналы \ NetConnectionChannel.as: 281] в mx.messaging.channels :: AMFChannel / internalSend () [E: \ DEV \ hero_private \ рамки \ проекты \ RPC \ SRC \ тх \ сообщениями \ каналы \ AMFChannel.as: 364] в mx.messaging :: Канал / отправить () [E: \ DEV \ hero_private \ рамки \ проекты \ RPC \ SRC \ ого \ сообщения \ Channel.as: 1002] в mx.messaging.channels :: PollingChannel / отправить () [E: \ DEV \ hero_private \ рамки \ проекты \ RPC \ SRC \ тх \ сообщениями \ каналы \ PollingChannel.as: 394] в mx.messaging :: ChannelSet / отправить () [E: \ DEV \ hero_private \ рамки \ проекты \ RPC \ SRC \ ого \ сообщения \ ChannelSet.as: 1429] в mx.messaging :: ChannelSet / channelConnectHandler () [E: \ DEV \ hero_private \ рамки \ проекты \ RPC \ SRC \ ого \ сообщения \ ChannelSet.as: 1084] на flash.events::EventDispatcher/dispatchEventFunction () на flash.events::EventDispatcher/dispatchEvent () в mx.messaging :: Channel / connectSuccess () [E: \ DEV \ hero_private \ рамки \ проекты \ RPC \ SRC \ ого \ сообщения \ Channel.as: 1148] в mx.messaging.channels :: AMFChannel / ResultHandler () [E: \ DEV \ hero_private \ рамочные \ проекты \ RPC \ SRC \ тх \ сообщениями \ каналы \ AMFChannel.as: 576]

Как видите, я расширил класс ArrayCollection и, согласно документации Adobe, ArrayCollection реализует интерфейс IExternalizable . Я решил локализовать проблему и создал простой класс, который реализует IExternalizable. Затем я расширил этот класс в каком-то другом классе MyChild и определил свойство MyChild в классе MyEntity. В этом случае я также получил исключение выше. Есть ли проблема в том, как я написал код, или это ошибка внутри flex?

Спасибо за любую помощь. Вопрос дублирован в моем блоге.

Ответы [ 3 ]

2 голосов
/ 13 октября 2012

Вы можете попробовать:

            registerClassAlias( "mx.collections.ArrayCollection", ArrayCollection);
            registerClassAlias("flex.messaging.io.ArrayCollection", ArrayCollection);
1 голос
/ 02 марта 2012

Попробуйте добавить псевдоним для MyCollection.

Я получил бесполезную ошибку # 2004, пока все мои классы, реализующие IExternalizable, не имели псевдонимов. В моем случае это было для персистентности (ViewNavigatorApplicationBase.persistNavigatorState = true), и в этом случае мне нужно было убедиться, что я вызвал registerClassAlias ​​достаточно рано при запуске, чтобы предшествовать View.deserializeData (). Событие preinitialize в приложении работает нормально.

0 голосов
/ 28 января 2014

Некоторые из ваших классов (де) сериализуются, вероятно, не связаны с проектом Flex.Попробуйте добавить следующее в ваш основной файл приложения / модуля:

private var forceReference:Array = [YourClass1, YourClass2];
...