Here is the XML format that I'm trying to create a web service for:
<test a1="a1">
<e1>e1</e1>
<e2 a2="a2">
<e3>e3</e3>
<e3>e3</e3>
</e2>
</test>
My problem is that I don't know how to create a Coldfusion (cfcomponent) SOAP web service that would conform to the XML format.
This is what I have come up with:
<cfcomponent style="document" wsversion = 1 >
<cffunction name="test" returntype="String" access="remote">
<cfargument type="String" required="no" name="e1"/>
<cfargument type="xml" required="no" name="e2" />
<cfreturn "ok">
</cffunction>
</cfcomponent>
As you can see, a1,a2 and e3 are left out as I have no idea how to define them in the cffunction, and I'm not sure if making e2 as xml type is correct.
Any help is appreciated.
you have to use
<cfsavecontent variable="textxml">
<cfoutput>
<test a1="a1">
<e1>e1</e1>
<e2 a2="a2">
<e3>e3</e3>
<e3>e3</e3>
</e2>
</test>
</cfoutput>
</cfsavecontent>
and pass the testxml variable to the function as xml type argument.
<cfinvoke method="test" component="compname" xmltest="#textxml#">
no need to send seperate arguments e1 e2...can send testxml variable to the function.
<cfcomponent >
<cffunction name="test" returntype="String" access="remote">
<cfargument type="xml" required="no" name="xmltest" />
<cfset newXML = XMLParse(arguments.xmltest)>
<cfdump var="#newXML#">
<cfreturn "ok">
</cffunction>
</cfcomponent>
Related
0 experience with ColdFusion over here.
Got this project dropped off at my desk which was written by somebody 4 years ago, the person doesn't work with my company any more.
Got the logs from the live hosted website, and the error seems to exist on this line.
Line 196:
<p>Click here to activate your account</p>
I believe it might have something to do with the fact that the URL exists in quotes and the parameters are not correctly being passed? But I am not certain by any means.
I do not have the code base to test it or debug it, just the live deployed website.
Happy to get any suggestions on how to proceed with this.
Thanks!
If your CFML code is hosted on both new and pre-CF11 ColdFusion servers, you may need to use a user-defined function (UDF) to fill the gap. We used the following code while slowly testing & migrating older applications from CF7 to 2016. (Just add these functions to your codebase and rename existing "CFusion_" tags to "Fusion_".)
Published 10/20/2005 by Barney Boisvert:
http://www.barneyb.com/barneyblog/2005/10/28/cfusion_encryptcfusion_decrypt-udfs/
<cffunction name="fusion_encrypt" output="false" returntype="string">
<cfargument name="string" type="string" required="true" />
<cfargument name="key" type="string" required="true" />
<cfset var i = "" />
<cfset var result = "" />
<cfset key = repeatString(key, ceiling(len(string) / len(key))) />
<cfloop from="1" to="#len(string)#" index="i">
<cfset result = result & rJustify(formatBaseN(binaryXOR(asc(mid(string, i, 1)), asc(mid(key, i, 1))), 16), 2) />
</cfloop>
<cfreturn ucase(replace(result, " ", "0", "all")) />
</cffunction>
<cffunction name="fusion_decrypt" output="false" returntype="string">
<cfargument name="string" type="string" required="true" />
<cfargument name="key" type="string" required="true" />
<cfset var i = "" />
<cfset var result = "" />
<cfset key = repeatString(key, ceiling(len(string) / 2 / len(key))) />
<cfloop from="2" to="#len(string)#" index="i" step="2">
<cfset result = result & chr(binaryXOR(inputBaseN(mid(string, i - 1, 2), 16), asc(mid(key, i / 2, 1)))) />
</cfloop>
<cfreturn result />
</cffunction>
<cffunction name="binaryXOR" output="false" returntype="numeric">
<cfargument name="n1" type="numeric" required="true" />
<cfargument name="n2" type="numeric" required="true" />
<cfset n1 = formatBaseN(n1, 2) />
<cfset n2 = formatBaseN(n2, 2) />
<cfreturn inputBaseN(replace(n1 + n2, 2, 0, "all"), 2) />
</cffunction>
<h2>cfusion_encrypt Test</h2>
<cfset key = "test" />
<cfoutput>
<table>
<cfloop list="barney,is,damn cool!" index="i">
<tr>
<td>#i#</td>
<td>#cfusion_encrypt(i, key)#</td>
<td>#fusion_encrypt(i, key)#</td>
<td>#cfusion_decrypt(cfusion_encrypt(i, key), key)#</td>
<td>#fusion_decrypt(fusion_encrypt(i, key), key)#</td>
</tr>
</cfloop>
</table>
</cfoutput>
Sounds like you're using now a version of ColdFusion server that does not have the built in cfusion_encrypt() function.
Try this, change
cfusion_encrypt(uu.username, application.encKey)
to
encrypt(uu.username, application.encKey,'CFMX_COMPAT','HEX')
I hope it helps.
My Custom tag expects a “query” in one of the attribute but my cfc function returns me the structure when I dump it. This is my function listScores()
<cffunction name="listScores" access="public" output="false" returntype="any"> <!--- not really scores, should probably rename this function - something to consider --->
<cfargument name="link" type="string" required="false" />
<cfargument name="linktype" type="numeric" required="false" default="2" /> <!--- 2 = ace inspection -> ace action--->
<cfargument name="reftype" type="numeric" required="false" default="2" /> <!--- 2 = equipment --->
<cfargument name="siteid" type="numeric" required="false" />
<cfargument name="archived" type="numeric" required="false" default="0" /> <!--- 0 = not archived --->
<cfargument name="acerefid" type="numeric" required="false" hint="ace_links refid" />
<cfargument name="apprefid" type="numeric" required="false" hint="equip tracker refid" />
<cfargument name="responseType" type="string" require="false" />
<cfif structKeyExists(arguments,'responseType') && arguments.responseType is 'query'>
<cfreturn OCRUD.listScores(argumentCollection=arguments) />
</cfif>
<cfreturn getArrayFromQuery(OCRUD.listScores(argumentCollection=arguments)) />
</cffunction>
When i dump the iEngine.listScores() i get the structure output.
I want to pass this iEngine.listScores() data to the custom tag which expects a query.
<cfmodule template="#request.library.customtags.virtualpath#excel.cfm" file="#filename#" sheetname="ACE Report">
<cfmodule template="#request.library.customtags.virtualpath#exceldata.cfm"
query="#variables.qlistScoreData#"
action="AddWorksheet"
sheetname="ACE Report"
colorscheme="blue"
useheaders="true"
contentformat="#{bold=true}#"
<!--- customheaders="#ListScore#" --->
>
<cfoutput>Excel Extract - ACE Report - #DateFormat(Now(),"d-mmm-yyyy")#</cfoutput>
</cfmodule>
</cfmodule>
I am getting Variable undefined error when i try to invoke a function from a cfc.
The best part is it is already defined above.
"IandI" is the cfc name.
Code snippet :
<cfparam name="TotalCorpAudits" default="0">
<cfset TotalAudits = TotalSiteAudits + TotalCorpAudits>
<cfinvoke component="#IandI#"
method="calcRate"
Cases="#TotalCorpAudits#"
Hours="#TotalAudits#"
iiFactor="1"
convertToPercent="true"
NumberFormatOn="true"
returnOnZeroHours="0"
returnOnNonNumericData="0"
returnvariable="TotalCorpRatioAudits"
>
Getting error at ... Cases="#TotalCorpAudits#"
CFC Code :
<cffunction name="calcRate" access="public" returntype="string"
displayname="calcs Rate" hint="" description="">
<cfargument name="Hours" required="Yes" type="string">
<cfargument name="Cases" required="Yes" type="string">
<cfargument name="IIFactor" required="No" type="numeric" default="200000">
<cfargument name="FormatMask" required="No" type="string" default="999.99">
<cfargument name="NumberFormatOn" required="No" type="boolean" default="false">
<cfargument name="returnOnZeroHours" required="No" type="string" default="0">
<cfargument name="returnOnNonNumericData" required="No" type="string" default="N/A">
<cfargument name="returnOnZeroCasesWithHours" required="No" type="string" default="0">
<cfargument name="convertToPercent" required="No" type="boolean" default="false">
CFINVOKE works like so:
<cfinvoke component="[CFC_FileName]" method="calcRate" returnvariable="TotalCorpRatioAudits">
<cfinvokeargument name="Hours" value="[whateverValueYouWant]">
<cfinvokeargument name="Cases" value="[whateverValueYouWant]">
</cfinvoke>
Notice a couple things: <cfinvokeargument> is underneath the <cfinvoke> tag. Also, I only used those two argument since they were required in the CFC, but you can add more if needed. Use https://wikidocs.adobe.com/wiki/display/coldfusionen/cfinvoke as a reference.
is the name of component comeing from a variables? Is IandI a variable? If it is not you dont have to wrap it in # signs. And that is what I think is causing the problem.
I've run into this a few times lately; it definitely seems like a bug in the ColdFusion engine. Seems as if the compiler is trying to evaluate the variable from within the CFC, rather than the calling page.
I've been able to work around it by defining my struct of arguments beforehand, then simply including the struct in the invoke().
<cfset argStruct = {argName1=val1,argName2=val2,argName3="hardcodedValue"}>
<cfinvoke component="cfcPath" method="methodName" argumentCollection="#argStruct#" />
So, I have allmost spend the night chasing a bug.... found it and no idea what is wrong.
I have script in Coldfusion which sends two emails. Both mails are in a mailer script which I'm calling with cfinvoke like so:
<cfinvoke component="form_mailer_basket" method="msg_order_seller">
... parameters
</cfinvoke>
<cfinvoke component="form_mailer_basket" method="msg_order_retailer">
... parameters
</cfinvoke>
Both mail parameters are all ok, but the 2nd mailer throws an error:
mailer orders
************************************************************************************
type: Application
************************************************************************************
message: Could not find the ColdFusion Component or Interface form_mailer_basket.
************************************************************************************
detail: Ensure that the name is correct and that the component or interface exists.
************************************************************************************
Question:
Can anyone tell me why the 2nd mail cannot find the component when the first script 5 lines above can?
Thanks!
EDIT:
Here is my code for calling both methods:
<cfif new_mail.recordcount GT 0>
<cfloop query="new_mail">
<cfset variables.newMail = new_mail.email_bestelleingang>
<cfinvoke component="form_mailer_basket" method="msg_order_seller">
<cfinvokeargument name="delDate" value="#variables.liefdatum_mail#"/>
<cfinvokeargument name="delMsg" value="#variables.bestell_text_mail#"/>
<cfinvokeargument name="delOrd" value="#LOCAL.Basket.bestelltyp#"/>
<cfinvokeargument name="mailto" value="#variables.newMail#"/>
<cfinvokeargument name="client" value="#LOCAL.Basket.re_firma#"/>
<cfinvokeargument name="rebate" value="#variables.kopf_rabatt#"/>
<cfinvokeargument name="sellerIln" value="#variables.iln_verkaeuferNEU#"/>
<cfinvokeargument name="ordNo" value="#variables.bestellnummer_neu#"/>
</cfinvoke>
</cfloop>
</cfif>
...
<cfloop query="active_check">
<cfif active_check.freigeschaltet NEQ "1" AND active_check.freigeschaltet NEQ "0">
<cfinvoke component="form_mailer_basket" method="msg_order_retailer">
<cfinvokeargument name="delDate" value="#variables.liefdatum_mail#" />
<cfinvokeargument name="delOrd" value="#LOCAL.Basket.bestelltyp#" />
<cfinvokeargument name="mailto" value="#variables.cusMail#" />
<cfinvokeargument name="client" value="#order_recipients.firma#" />
<cfinvokeargument name="rebate" value="#variables.kopf_rabatt#" />
<cfinvokeargument name="sellerIln" value="#variables.iln_verkaeuferNEU#" />
<cfinvokeargument name="ordNo" value="#variables.bestellnummer_neu#" />
<cfinvokeargument name="total" value="#variables.gesamtsumme#" />
<cfinvokeargument name="menge" value="#variables.gesamtmenge#" />
<cfinvokeargument name="curr" value="#variables.waehrung#" />
<cfinvokeargument name="agentF" value="#variables.agentFirma#" />
<cfinvokeargument name="agentN" value="#variables.agentName#" />
</cfinvoke>
</cfif>
</cfloop>
First one works, second one doesn't. Method names are correct, all parameters are ok (I know I should use an argumentsColletion...), so I'm clueless and need to take a nap. Checking back later!
And the cfc:
<cfcomponent output="false" hint="basket mailing cfc - sends out all basket related mail messages">
<!--- LOAD LANGUAGES --->
<cfinclude template="../templates/tmp_lang.cfm">
<!--- INIT --->
<cffunction name="Init" access="public" returntype="any" output="false" hint="Initialize">
<!--- nothing here for now --->
<cfreturn true />
</cffunction>
... msgs like this:
<!--- NEW ORDER SELLER --->
<cffunction name="msg_order_seller" access="public" output="false" hint="msg for new orders">
<cfargument name="delDate" type="date" required="true" hint="delivery date" />
<cfargument name="delMsg" type="string" required="true" hint="text message by retailer" />
<cfargument name="delOrd" type="string" required="true" hint="order type pre/asap" />
<cfargument name="mailto" type="string" required="true" hint="email adress" />
<cfargument name="client" type="string" required="true" hint="buyer" />
<cfargument name="rebate" type="string" required="true" hint="rebate 1/0" />
<cfargument name="sellerIln" type="string" required="true" hint="seller ILN" />
<cfargument name="ordNo" type="string" required="true" hint="order number" />
<cfprocessingdirective suppresswhitespace="No">
<cfmail
TO="#mailto#"
FROM="automailer#..."
SERVER="mail.bbb.de"
USERNAME="ddd"
PASSWORD="123456"
SUBJECT="#tx_automailer_order_new# - #client#">
#tx_automailer_default_anrede#
#tx_automailer_order_info#
#tx_automailer_order_type#: #ordertype# #rebateTxt#
#tx_automailer_order_del#: #deliveryDate#
#tx_automailer_order_no#: #ordNo#
#tx_automailer_order_date#: #DateFormat(now(),"dd.Mm.yyyy")#
#tx_kaeufer#: #client#
#tx_automailer_order_msg#:
#delMsg#
#tx_automailer_order_iln#: #sellerIln#
#tx_automailer_default_gruss#
#tx_automailer_default_team#
-------------
#tx_automailer_default_disclaimer#
</cfmail>
</cfprocessingdirective>
<cfreturn />
</cffunction>
...
</cfcomponent>
If you just want to solve your problem instead of trying to figure out what is causing it, I have a suggestion. Instead of using the cfinvoke tag for the same component many times, use either cfobject or CreateObject() to make just one instance of it. Then call the methods directly.
Even if you do get your current approach to work, it will be slower than my suggestion. cfinvoke creates an object each time you call it and that takes processing time.
Are you sure that both methods exist and are public?
Using cfinclude in cfc is NOT good practice, though admittedly I had to do it too on occasions.
Your error Could not find the ColdFusion Component or Interface form_mailer_basket seems to imply that something happens to the component itself - I suspect it has something to do with your return statement in Init() method.
In earlier versions of CF (I think around version 6/7 maybe 8) you could overwrite your function by setting identically named variable inside your cfc. You did not mention the CF version that you are running.
I am creating a CFC called "core_appdata". This CFC will hold the core stored procedures for an application. Example....
<cfcomponent displayname="core_appdata" hint="I Return Core App Data" output="no">
<cffunction name="getprogram_list">
<cfargument name="getstoredproc_input_campaignid" type="string" required="false">
<cfargument name="getstoredproc_input_filtertestrecs" type="string" required="false">
<cfargument name="getstoredproc_input_startdate" type="date" required="false">
<cfargument name="getstoredproc_input_enddate" type="date" required="false">
<cfargument name="getstoredproc_input_listtypeid" type="string" required="false">
<cfargument name="getstoredproc_input_listid" type="string" required="false">
<cfargument name="getstoredproc_input_appenvr" type="string" required="false">
<cfset var rst_getprogram_list ="">
--- stored proc ---
<cfstoredproc procedure = "p_adb_getprogram_list">
</cfstoredproc>
<cfreturn rst_getprogram_list />
</cffunction>
</cfcomponent>
I would also like to create a CFC called "core_appdata_grids". This CFC would be used to bind to cfgrids and allow paging etc. In a perfect world, this CFC would get its data from the method/function "getprogram_list" in the CFC "core_appdata" above. Example...
<cfcomponent displayname="core_appdata_grids" hint="I Return Core App Data For CFGrids " output="no">
<cffunction name="getprogram_list_grid">
<cfargument name="page" required="no" />
<cfargument name="pageSize" required="no" />
<cfargument name="gridsortcolumn" required="no" />
<cfargument name="gridsortdirection" required="no" />
<cfargument name="getstoredproc_input_campaignid" type="string" required="false">
<cfargument name="getstoredproc_input_filtertestrecs" type="string" required="false">
<cfargument name="getstoredproc_input_startdate" type="date" required="false">
<cfargument name="getstoredproc_input_enddate" type="date" required="false">
<cfargument name="getstoredproc_input_listtypeid" type="string" required="false">
<cfargument name="getstoredproc_input_listid" type="string" required="false">
<cfargument name="getstoredproc_input_appenvr" type="string" required="false">
<cfset var rst_getprogram_list_grid ="">
--- get data ---
<cfreturn queryconvertforgrid(rst_getprogram_list_grid, page, pagesize) />
</cffunction>
</cfcomponent>
Questions:
Is this possible? If so, how is it done?
If so, is this best practice when working with CFCs?
If not, what is the best way to share data between CFCs
Thank you in advance for your time in helping me with this question.
OC
I can't see the name of the cfc that produces the grid but just extend the base cfc which will inherit all the methods.
<cfcomponent extends="core_appdata">
<cffunction name="getprogram_list_grid">
<cfargument name="page" required="no" />
<cfargument name="pageSize" required="no" />
<cfargument name="gridsortcolumn" required="no" />
<cfargument name="gridsortdirection" required="no" />
<cfargument name="getstoredproc_input_campaignid" type="string" required="false">
<cfargument name="getstoredproc_input_filtertestrecs" type="string" required="false">
<cfargument name="getstoredproc_input_startdate" type="date" required="false">
<cfargument name="getstoredproc_input_enddate" type="date" required="false">
<cfargument name="getstoredproc_input_listtypeid" type="string" required="false">
<cfargument name="getstoredproc_input_listid" type="string" required="false">
<cfargument name="getstoredproc_input_appenvr" type="string" required="false">
<cfset var rst_getprogram_list_grid = super.getprogram_list() />
<cfreturn queryconvertforgrid(rst_getprogram_list_grid, page, pagesize) />
</cffunction>
</cfcomponent>
If you don't want to extend the CFC, especially if that's not being true to your model, you could just call the other CFC:
<cfset var rst_getprogram_list_grid = createObject("component","core_appdata").getprogram_list() />
OR even better somewhere above it all set:
<cfset request.core_appdata=createObject("component","core_appdata")>
And then in your CFC:
<cfset var rst_getprogram_list_grid = request.core_appdata.getprogram_list() />
Just a few options.