Actionscript Webservice set result format as e4x - apache-flex

I'm trying to use Webservice component in my Flex 4 application.
I need to use this in Actioncript and not using MXML tags.
I'm able to invoke the WSDL operations successfully, but the resultFormat is Object by default.
How do I set it to e4x?
var lookupService:WebService = new WebService();
lookupService.wsdl =url;
lookupService.loadWSDL();
lookupService.doLookup.addEventListener(ResultEvent.RESULT, lookupResultHandler);
lookupService.doLookup.addEventListener(FaultEvent.FAULT, faultHandler);
lookupService.doLookup(lookupString);
I tried to set the format by
lookupService.resultFormat = "e4x";
But this is not working. The calls are not even going through when I do this.
Can you please provide your suggestions for implementing this using AS3?

If you take a look at the two web service classes, you'll realize that resultFormat is not a property on either of them. Resultset is a property on the operations array.
If that doesn't help, you'll have to quantify "not working." What isn't working? Are you getting compile errors? Are you getting runtime errors? IS the data not being returned? Is the data not be returned as XML?
You'll probably have to set this up in MXML and dissect the generated ActionScript to figure out the appropriate AS3 syntax.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/rpc/soap/WebService.html

Related

ActivityBuilder.Implementation doesn't include NamespacesForImplementation when serialized

I'm having a problem serializing to xaml a WorkflowService that includes an ActivityBuilder for its Body parameter. The ActivityBuilder contains C# expressions and the serialized WorkflowService doesn't activate because some C# expressions refer to custom types. The actual error is "Type 'SomeTypeIPassToAnArgument' is not defined".
My ActivityBuilder is created from a xaml file which includes a TextExpression.NamespacesForImplementation element. This is missing when the WorkflowService is serialized and it seems this is the cause of the problem.
I found that if I serialize the ActivityBuilder itself, the namespaces are included, but using ActivityBuilder.Implementation fails. Unfortunately, when I build the WorkflowService to serialize I have to use ActivityBuilder.Implementation as its Body parameter. I tried using the TextExpression.SetNamespacesForImplementation method to ensure these were attached to the implementation but that didn't help.
The following snippet shows what I'm trying to do and where it's failing.
var loadedXaml = File.ReadAllText(#"C:\workflow.xaml");
Assert.IsTrue(loadedXaml.Contains("NamespacesForImplementation"));
var xamlReader = new XamlXmlReader(new StringReader(loadedXaml));
var builderReader = ActivityXamlServices.CreateBuilderReader(xamlReader);
var builder = XamlServices.Load(builderReader) as ActivityBuilder;
// namespaces are available in the builder itself
Assert.AreNotEqual(0, TextExpression.GetNamespacesForImplementation(builder).Count);
// when saving, the assert fails because the namespaces aren't serialized
var savedXaml = XamlServices.Save(builder.Implementation);
Assert.IsTrue(savedXaml.Contains("NamespacesForImplementation"));
Any idea why this isn't working, or if there's an alternative approach I could use that would work? Ultimately my aim is to be able to load workflows from xaml and incorporate them in a serialized WorkflowService that I can host in an MVC app using a VirtualPathProvider.
Thanks!
You can't use ActivityBuilder as the body of a WorkflowService, ActivityBuilder is just intended to manipulate an Activity at design time. To convert your ActivityBuilder to an Activity, use ActivityXamlServices.CreateBuilderWriter.
You can leverage XamlServices.Transform to pipe a XamlReader over your ActivityBuilder to the writer you create in ActivityXamlServices.CreateBuilderWriter.

NHibernate.IFutureValue<> when serialized includes .Value

I'm building an ASP.NET (2.0, no, I can't change it) site with NHibernate, and have a custom JSON converter so I can not-serialize properties I want hidden from the client. This lets me just return the objects, and never have to worry about their serialized values - they're always secure.
Unfortunately, it appears that if I use query.FutureValue<class>(), the object that gets serialized is first the NHibernate.Impl.FutureValue<class> and not my entity, which means I get JSON that looks like this if I throw it in a dictionary and return it to the client:
{key: { Value: { /* my serialized object properties */ } }
Previously I discovered that I can't get any interfaces to work in ASP's JavaScriptConverter implementations... only regular or abstract classes. So returning typeof(IFutureValue<MyBaseClass>) as a supported type means my converter is completely ignored. I can catch MyBaseClass, because I refactored things earlier to use an abstract base instead of an interface, but not the interface.
And then I discover that the FutureValue implementation in .Impl is internal to the assembly, or some other such nonsense that only serves to make my .NET experience even more painful. So I can't use typeof(FutureValue<MyBaseClass>) to handle it all, because FutureValue exists only in my debugging sessions.
Is there a way to get the class type out of the assembly? Or a way to convince ASP that interfaces do in fact have uses? Or might there be some superclass I can access that would let me get around the whole issue?
Help! I like my Futures, it lets me batch a whole heck-ton of calls at once!
(if something isn't clear, or you want more code, by all means, ask! I can post quite a bit.)
If I'm understanding you correctly, it seems you are mixing things a together a little bit.
It sounds like you're trying to serialize an instance of query.FutureValue<class>(), which unsurprisingly gives you just that: a JSON object where the Value fields has JSON representing your entity.
To me it sounds like you really want to just serialize query.FutureValue<class>().Value.
Using NHibernate futures like this gives you little benefit though, so you're probably after something like:
var future1 = query1.FutureValue<SomeEntity>();
var future2 = query2.FutureValue<AnotherEntity>();
var json1 = serializer.Serialize(future1.Value); //<BAM! Multi-query gets fired!
var json2 = serializer.Serialize(future2.Value);
Does that make sense?

Coldfusion returning typed objects / AMF remoting

Is the same possible in ColdFusion?
Currently I am using .Net/Fluorine to return objects to the client.
Whilst in testing I like to pass strings representing the select statement and the custom object I wish to have returned from my service.
Fluorine has a class ASObject to which you can set the var 'typeName'; which works great.
I am hoping that this is possible in Coldfusion. Does anyone know whether you can set the type of the returned object in a similar way.
This is especially helpful with large collections as the flash player will convert them to a local object of the same name thus saving interating over the collection to convert the objects to a particular custom object.
foreach (DataRow row in ds.Tables[0].Rows)
{
ASObject obj = new ASObject();
foreach (DataColumn col in ds.Tables[0].Columns)
{
obj.Add(col.ColumnName, row[col.ColumnName]);
}
obj.TypeName = pObjType;
al.Add(obj);
}
Many thanks,
Yes, it works and is built right in so you don't have to use an external server side piece.
ColdFusion Components (CFCs) are the ColdFusion version of an Class.
ColdFusion's Flash/Flex Remoting Gateway will do the automatic conversion of CFCs into ActionScript objects.
Remember that CF is Java based; so the paths and class names are case sensitive. I assume .NET is not like that.
The CFC and ActionScript object should list all properties in the same order. In AS3, you can define them as public variables; in the CFC you should define them using the cfproperty tag. The ActionScript Object should use the RemoteClass metadata tag to specify the absolute location of the CFC. The CFC's cfcomponent tag should specify the alias attribute which is the absolute path location of the CFC Object.
If the CFC method in your service returns an object; the return type on your cffunction tag should be the absolute path to the CFC Object.
I would expect a lot of this is similar to what you've been doing with .NET; just with different syntax. I'm pretty sure you have to enable Flex / Flash Remoting in the CFADmin before any of this will work.
There should be a CF to Flex data type conversion chart somewhere in the CF Docs.
You can also return a struct with a special key called 'type' with the value of the AS class that the properties represent, and Flex will populate those objects.
For example
{
id=2,
name=kevin,
__type__=com.company.user
}
(note that is 'underscore underscore type underscore underscore', the formatting is bein stripped)

Two different HTTPService classes in Flex

Why are there two different HTTPService classes in Flex?
this
and
this
And the second one inherits the first one.
Why couldn't there be a single class combining the two?
One of the objects (the first link you posted) is the HTTPService Object itself.
The second is the object that wraps the HTTPService object and gives it the additional functionality for the <mxml /> tag.
The two probably weren't combined because you don't necessarily need the implementation of the IMXMLObject and IMXMLSupport interfaces every time you need an HTTService object.
mx.rpc.http.mxml.HTTPService can also handle concurrency while the other can't.
Edit:
Although in the online documentation I see concurrency as a property of both, several sources say thats not true(and my tests didn't work when I first tried using it). Also the concurrency package is only imported into the mxml.HTTPService, not the base rpc class.
Bug Comment
Mederator comment on the docs page
There appear to be more error handling features in the URLLoader class. Using MXML to create your HTTPService is not a big difference though.
// ActionScript Style
private function myService():void {
var service:HTTPService = new HTTPService();
...service.parameters = value;...
service.send();
}
or
< !-- MXML Style -- >
< mx:HTTPService >
...< parameters >...
< /mx:HTTPService >
The first is a member of the mx.rpc.http package and is used in ActionScript code. The other version of the HTTPService class is a sublass of the first and is a member of the mx.rpc.http.mxml package. This is the version you use when you instantiate the object with the tag.
The versions are nearly identical with two significant differences: only the MXML Version implements the showBusyCursor property, which casuses an animated curser top be displayed for the duration of an HTTPService request/response cycle, and the concurrency property, which determines how multiple concurrent requests to the same network resource are handled.
The concurrency property isn't implemented in the version of the HTTPService class typically used in ActionScript because, when using ActionScript you commonly create a new HTTPService object for each new request.
Source: Adobe Flex 3 Bible - David Gassner

React to change on a static property

I'm re-writing an MXML item renderer in pure AS. A problem I can't seem to get past is how to have each item renderer react to a change on a static property on the item renderer class. In the MXML version, I have the following binding set up on the item renderer:
instanceProperty={callInstanceFunction(ItemRenderer.staticProperty)}
What would be the equivalent way of setting this up in AS (using BindingUtils, I assume)?
UPDATE:
So I thought the following wasn't working, but it appears as if Flex is suppressing errors thrown in the instanceFunction, making it appear as if the binding itself is bad.
BindingUtils.bindSetter(instanceFunction, ItemRenderer, "staticProperty");
However, when instanceFunction is called, already initialized variables on the given instance are all null, which was the cause of the errors referenced above. Any ideas why this is?
You have 2 options that I am aware of:
Option 1
You can dig into the code that the flex compiler builds based on your MXML to see how it handles binding to static properties. There is a compiler directive called -keep-generated-actionscript that will cause generated files to stick around. Sleuthing through these can give you an idea what happens. This option will involve instantiating Binding objects and StaticPropertyWatcher objects.
Option 2
There is staticEventDispatcher object that gets added at build time to classes containing static variables see this post http://thecomcor.blogspot.com/2008/07/adobe-flex-undocumented-buildin.html. According to the post, this object only gets added based on the presence of static variables and not getter functions.
Example of Option 2
Say we have a class named MyClassContainingStaticVariable with a static variable named MyStaticVariable and another variable someobject.somearrayproperty that we want to get updated whenever MyStaticVariable changes.
Class(MyClassContainingStaticVariable).staticEventDispatcher.addEventListener(
PropertyChangeEvent.PROPERTY_CHANGE,
function(event:PropertyChangeEvent):void
{
if(event.property == "MyStaticVariable")
{
someobject.somearrayproperty = event.newValue as Array;
}
});
I think you need to respond to the "PropertyChanged" event.
If you're going to do that, use a singleton instead of static. I don't think it will work on a static. (If you have to do it that way at all, there are probably a couple ways you could reapproach this that would be better).
var instance:ItemRenderer = ItemRenderer.getInstance();
BindingUtils.bindProperty(this, "myProperty", instance, "theirProperty");
After fiddling with this for a while, I have concluded that this currently isn't possible in ActionScript, not even with bindSetter. It seems there are some MXML-only features of data bindings judging by the following excerpt from the Adobe docs (though isn't it all compiled to AS code anyways)?
You cannot include functions or array
elements in property chains in a data
binding expression defined by the
bindProperty() or bindSetter() method.
For more information on property
chains, see Working with bindable
property chains.
Source: http://livedocs.adobe.com/flex/3/html/help.html?content=databinding_7.html
You can create a HostProxy class to stand in for the funciton call. Sort of like a HostFunctionProxy class which extends from proxy, and has a getProperty("functionInvokeStringWithParameters") which will invoke the function remotely from the host, and dispatch a "change" event to trigger the binding in typical [Bindable("change")] Proxy class.
You than let the HostProxy class act as the host, and use the property to remotely trigger the function call. Of course, it'd be cooler to have some TypeHelperUtil to allow converting raw string values to serialized type values at runtime for method parameters (splitted by commas usually).
Example:
eg.
var standInHost:Object = new HostFunctionProxy(someModelClassWithMethod, "theMethodToCall(20,11)");
// With BindingUtils.....
// bind host: standInHost
// bind property: "theMethodToCall(20,11)"
Of course, you nee to create such a utlity to help support such functionality beyond the basic Flex prescription. It seems many of such (more advanced) Flex bindings are usually done at compile time, but now you have to create code to do this at runtime in a completely cross-platform Actionscript manner without relying on the Flex framework.

Resources