CF8 Hidden Gem: New ArgStruct argument for createObject with web services
Note: This blog post is from 2007. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.Here's another hidden gem in CF8: did you know that there's a new optional "ArgStruct' argument for use with createObject(), when using it to invoke web services?
Following on my previous note about a new RefreshWSDL option in CF8 for CFINVOKE and CFOBJECT, I mentioned there that it was also an option in the createObject() function, but naturally it can't be passed as a tag attribute like with those above.
Instead, it's enabled using this new ArgStruct argument. Technically, it's not "named" ArgStruct but rather it's simply a new optional 3rd argument you can specify when invoking a web service (the term "argStruct" simply comes from the CF docs for the function, where it refers to it by that name. (While yo umay notice that the docs indicate this also allows setting a timeout for the web service invocation, note that that only times out the requesting of the WSDL, not subsequent method calls against the object.)
Anyway, in that structure you create, you simply define RefreshWSDL as a key within it, all of which is passed into the createObject() function as that 3rd argument:
wsargs = structnew();
wsargs.refreshwsdl="yes";
somevar = createobject("webservice","http://[server]/[webserviceurl]",wsargs);
...
</cfscript>
Of course, you could just as easily do all the above in 3 CFSET tags. It doesn't matter. The key is the addition of the 3rd argument to the createObject(). And it doesn't matter at all what you call the structure (I named mine "wsargs").
Now, you may think this approach seems clumsy, and ask, "why didn't they just permit the refreshWSDL itself as a new argument on the createObject()?". It's a fair question.
But it turns out there's actually a little more to this new ArgStruct option, and it's different enough that I'll talk about it in a separate entry.
For more content like this from Charlie Arehart:Need more help with problems?
- Signup to get his blog posts by email:
- Follow his blog RSS feed
- View the rest of his blog posts
- View his blog posts on the Adobe CF portal
- If you may prefer direct help, rather than digging around here/elsewhere or via comments, he can help via his online consulting services
- See that page for more on how he can help a) over the web, safely and securely, b) usually very quickly, c) teaching you along the way, and d) with satisfaction guaranteed
Expression Error: Complex object types cannot be converted to simple values. The expression has requested a variable or an intermediate expression result as a simple value, however, the result cannot be converted to a simple value. Simple values are strings, numbers, boolean values, and date/time values. Queries, arrays, and COM objects are examples of complex values.
The error is one where you are trying to treat as a simple object something that's complex. Just try CFDUMPing whatever it's referring to. That will show you what it is. For instance, if you're trying to view the result of calling some web service, and you're CFOUTPUTing it (or using it in some expression), maybe it's not a simple string or number. Maybe it's an array, or struct, or query. That's exactly what the error message says. :-)
If you're saying the error occurs when you add this refreshwsdl feature, in a web service call that used to work, it may indicate that the web service did indeed change since CF had cached your first call to it, and now its result isn't what it used to be. That's just a guess, though.
But seriously, I think there are some incompatibility issues between CF 7 and CF 8 webservice calls because I do get an error from CF 7 about a comment included in CF 8 generated wsdl xml output. CF 7 tries to consume the service but gags on the comment within the CF 8 wsdl xml. I could be wrong, I'm still troubleshooting this issue.
Thanks
Further, you say that you get an error trying to consume a CF8 web service from CF 7. I can confirm that works at least in the tests I try (and I'm sure Adobe and beta testers also would have tried it), but you could have some specific example that fails. What is your CF8 web service returning? And are you by any chance using the new ReturnFormat attribute in the CFFUNCTION being called? It shouldn't affect it (it should only affect calling it from a browser, not as a web service), but seems worth asking.
Anyway, for debugging purposes, I'd propose that you separate out your efforts. Prove that the web service you're calling responds from the edition in which you've written it. Call a CF8 service from CF8, and a CF7 service from CF7. Beyond that, if you want to share what you see, we'll try to help--but really, I sense that it has nothing to do with the feature described here--and so while I don't like to provide support via the blog, let's finish this out since you've started it. :-)
Just so you know, had I read this article Friday at work; I would have had a much better weekend. This Hidden Gem seems to be the solution to a major headache of mine.
Thanks so much for all you do for the CF Community!
Thanks again!