Method cannot be found when invoking Webservice API - web-services

While invoking the Webservice API for the GetTablesBin method, I'm getting the error Web service operation GetTablesBin with parameters cannot be found.
Webservice Calling code
<cfinvoke
webservice="http://www.argusmedia.com/ArgusWSVSTO/ArgusOnline.asmx?wsdl"
method="GetTablesBin"
returnvariable="binResponse">
<cfinvokeargument name="authToken" value="#AuthToken#"/>
<cfinvokeargument name="tableNames" value="#tablename#"/>
</cfinvoke>
I can see the method running fine using the SOAPUI client.
While digging further, found the method class to be missing in the Coldfusion stubs folder as well.
Any pointers would be really helpful?

Web service operation GetTablesBin with parameters
{...} cannot be found.
Notice it says "with parameters"? Subtle difference, but it either means a) the method does not exist at all OR b) it does exist, but is receiving the wrong number or type of arguments. In this case the problem is "b)".
When troubleshooting web service issues, it is often helpful to create an instance of the web service, then dump that object to see which arguments the method requires. According to CF11, the "GetTablesBin" method expects two arguments: a String and an ArrayOfString. However, the current code passes in two String's. Hence the error.
Code:
<!--- Add {refreshWSDL=false} if needed --->
<cfset ws = createObject("webservice"
, "http://www.argusmedia.com/ArgusWSVSTO/ArgusOnline.asmx?wsdl")>
<cfset writeDump(ws)>
Dump:
An ArrayOfString is a slightly strange beast:
... there is no direct mapping of ArrayOfString. So it is essentially
treated as a structure, just like any other complex type. If you look
at the wsdl, ArrayOfString contains a single key named string, whose
value is an array of type="s:string":
To resolve the error, simply create a structure with the proper key and pass it into the cfinvoke call. (Though personally I prefer createObject() which is a little less bulky IMO)
<cfset arrayOfStrings = ["tableName1","tableName2"] />
<cfset tableNames.string = arrayOfStrings />
<cfinvoke ....>
<cfinvokeargument name="authToken" value="#AuthToken#"/>
<cfinvokeargument name="tableNames" value="#tableNames#"/>
</cfinvoke>

Related

Sending an email with CFMAIL inside of a CFSCRIPT

I wrote an application at work that uses a few CFC's- I'm having some errors but I want to actually mail the errors out because the application is live and they are happening rarely.
I can't stop what's currently running to troubleshoot.
Does anyone have any experience/can point me towards doing cfmail inside of a cfc/cfscript? More specifically, inside of a try/catch within cfscript.
We're running ColdFusion 9 which doesn't support <cfmail> inside of <cfscript>.
The mail CFC is built in to CF9 and above. You can use it in cfscript and it shouldn't matter where you implement it - within a try/catch block should be fine in onError.
Adobe has an example of the usage in their documentation for CF9:
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSe9cbe5cf462523a0693d5dae123bcd28f6d-7ff9.html
Write a new cfc with a function to send an email and then include that within the try/catch. Something like below will work
sendMail.cfc (missing a lot of things, but this is the structure)
<cfcomponent output="false">
<cffunction name="sendEmail">
<cfargument name="errorMessage">
<cfmail>
<cfdump var="#arguments.errorMessage#">
</cfmail>
</cffunction>
</cfcomponent>
try {
//code here
} catch (any e) {
var sendEmail = new sendMail();
sendEmail.sendEmail(e);
}

Problems handling 404 errors in ColdFusion 10 on Win2k8 R2 x64?

I'm having difficulties handling 404 errors correctly in ColdFusion 10 on Windows 2008 R2 x64 using a custom error handler (Execute URL) in IIS. I've done this in previous versions of CF with no problems. In IIS, under the web site features, I open "Error Pages" and set it to execute "/404.cfm" for all 404 errors.
The problem I'm having is that the output of the 404.cfm page is not completely being sent back to the browser and the page doesn't load correctly. Sometimes I get nothing back, other times I get 1K, other times I get a little bit more. It's very inconsistent.
Along with setting the 404.cfm handler in IIS, I am also calling it in the onMissingTemplate() method inside Application.cfm:
<cffunction name="onMissingTemplate"
returnType="boolean"
output="true">
<cfargument name="thePage" type="string" required="true">
<cftry>
<cfmodule template="../../../404.cfm" thePage="#Arguments.thePage#">
<cfcatch>
<cfoutput><p>An error occurred</p></cfoutput>
</cfcatch>
</cftry>
<cfreturn true />
</cffunction>
Inside my 404.cfm error handler, I'm calling:
<cfheader statuscode="404" statustext="Not Found">
... and then I output a bunch of stuff.
When I remove the call to cfheader in 404.cfm, the error handler loads correctly [for ColdFusion requests]. That's because nothing is going through IIS - instead, it's simply going through the onMissingTemplate() method in ColdFusion. However, the response header gives me a 200 status code, which is a problem! It needs to be a 404 status code for obvious reasons.
When I include the cfheader call, OR when a non-ColdFusion page is being requested (IIS will generate the 404 status code), the output of my 404.cfm handler is not completely returned to the browser. I think has something to do with IIS getting its hands on the action.
I did report this in the CF bug database, but I'm wondering if there's something I'm doing wrong. The bug is here: https://bugbase.adobe.com/index.cfm?event=bug&id=3488063
This bug is indeed finally fixed for CF10, with update 11. See http://blogs.coldfusion.com/post.cfm/coldfusion-10-update-11-an-update-with-50-fixes. It only mentions it in passing ("8. Web Container/Tomcat - CGI.server_port, IIS custom error handlers"), but it is there.
And the bug report referenced above has also been updated to indicate that it's fixed with this update.
But let me offer a word of warning: some folks are saying (at the bug report) that they are finding the problem NOT fixed even after applying the update.
There's a very likely explanation: please note that after applying update 11, you MUST either update or rebuild the web connector for IIS. For more on that, see http://blogs.coldfusion.com/post.cfm/coldfusion-10-does-the-connector-need-to-be-re-installed-for-update-11.
More specifically, if you look at the coldfusion10\config\wsconfig[nn\ folder (where nn is a number, of which folders you have more than one), and your isapi_redirect.dll is not dated in May 2013, then you have NOT yet done the needed update 11 and will still seem to have the problem.
And be sure to update all of your connectors, if you have more than one such folder under wsconfig. If after doing that, and restarting IIS perhaps, if you are still having the problem, then do report back at the bug report confirming that. Perhaps there may be something else to explain it, but we'd want to rule this issue out first.
I've updated the bug base bug but will re-iterate my workaround here.
I was able to kludge a fix by wrapping the content of the 404 handler using CFSaveContent then forcibly writing the content length:-
<cfsavecontent variable="thePage">
Your 404 code here
</cfsavecontent>
<cfcontent reset="Yes" type="text/html"><cfheader name="Content-Length" value="#len(thePage)#"><cfoutput>#thePage#</cfoutput><cfabort>
Note: I have the cfcontent through to the cfabort on one line so there's no additional whitespace.
CF9 doesn't seem to set a content length header but it doesn't seem to make a difference.. CF10 however ... Tomcat must not be adding the magic ingredient at the end of the CF handling and passing it back to IIS.
I have not found update 11 to work. Even after connector updates. Another kludgey fix:
<CFPARAM default="0" name="URL.r">
<CFPARAM default="0" name="URL.t">
<CFSET ErrUrl = "/cfm/global/404error.cfm">
<CFIF URL.r IS 0>
<CFIF FindNoCase( ".htm", CGI.HTTP_REFERER ) GT 0>
<CFLOCATION url="#ErrUrl#?r=1&t=htm">
</CFIF>
<CFIF FindNoCase( ".cfm", CGI.HTTP_REFERER ) GT 0>
<CFLOCATION url="#ErrUrl#?r=1&t=cfm">
</CFIF>
<CFLOCATION url="#ErrUrl#?r=1">
</CFIF>
<CFIF URL.t IS "htm">
<CFHEADER statuscode="404" statustext="Page Not Found">
</CFIF>
placed at the top of your error page (change your ErrUrl to point to your error page) works for both CFM and HTM(L) pages. It's gross, but seems to work.
Inside my 404 handler, I added:
<cfheader statuscode="404" statustext="Not Found">
<cfheader name="Connection" value="Close"> <!--- this is the fix! --->
Closing the connection seems to work for some reason.
And to output the page, I'm doing:
<cfcontent reset="Yes" type="text/html">
<cfheader name="Content-Length" value="#Len(fullpage)#">
<cfoutput>#fullpage#</cfoutput>
... where the variable fullpage is the content of the 404 handler.
Now I can now consistently return both a 404 status code error AND the entire contents of my error page. However, when a non-ColdFusion page is requested, the CGI values are not correct. Prior to CF10, I could get the requested page by looking at the CGI parameters, specifically CGI.query_string, which used to look like: “404;http://www.example.com/some/file.html” Now I’m getting: “404;http://www.example.com/jakarta/isapi_redirect.dll”, which makes it impossible to get the requested page.
However, the fact that I can now return an entire document makes this at least a partial workaround to the bug, which is still open (after over a year of CF10 being released)! For now, instead of trying to figure out what page was requested and looking at my sitemap, I'm simply outputting a standard "page not found" error.
I should also mention that I'm using the same 404 handler in the onMissingTemplate method in Application.cfc. The requested page is passed into this method, which I then pass to my 404 handler in the Attribute scope, and I call my 404 handler as a cfmodule. So this is a complete solution when it's a ColdFusion page being requested, and only a partial solution when a non-CF page is requested (since we can't determine the requested file).
fix i came up with after trial and error
is in the custom404.cfm that you have pathed to in iis7
put the following code
<cfinclude template="/inc_mypathtoroot/my404.cfm">
<cfheader name="Connection" value="Close">
then create the file my404.cfm in the root (the path for the include will need to be your include path)
in the my404.cfm file put your processing code.
BUT DO NOT USE <CFABORT> ANYWHERE IN THAT FILE AS IT WILL CAUSE THE CONNECTION TO BE RESET.

ColdFusion 10 application.cfc error: counting number of active sessions

In the adobe coldfusion 10 documentation, Defining the application and its event handlers in Application.cfc, there is a sample Application.cfc containing the function below. After looking at the code, I am wondering if there is a typo/bug in the following code:
<cffunction name="onSessionStart">
...
<cflock timeout="5" throwontimeout="No" type="EXCLUSIVE" scope="SESSION">
<cfset Application.sessions = Application.sessions + 1>
</cflock>
...
</cffunction>
Should it be:
(A) cflock ... scope="SESSION"
or
(B) cflock ... scope="APPLICATION"
?
If it is (A) then I am confused. Can someone explain why?
This is a duplicate of my answer to the same question asked on the Adobe forums:
Don't be confused... it's an error in the docs. You could do Adobe a
favour by commenting at the bottom of the page: they do monitor those
comments (they don't always react, but the do monitor them).
onSessionStart() is intrinsically single-threaded as far as the
session scope goes: it's only ever run once per session (when the
session starts...). On the other hand the code in question def wants
to single-thread access to that application-scoped variable as we
don't want two simultaneous sessions hitting it for any given single
value of it (if that makes sense).
You always lock the SCOPE that you are writing to. In this case it would be APPLICATION.

Debugging a Photo Uploader/ CfCatch

I seem to be having an issue with the photo uploading function on a site I'm working on.
<cftry>
<cffile
action="upload"
destination="#physicalPath#\PHOTOS"
filefield="photo"
nameconflict="makeunique"
accept="image/jpeg, image/pjpeg"
result="mypicture"
/>
<cfset OutcomeID = "#FORM.OutcomeID#"/>
<!---Inserts file name and outcome id into Uploads table in the database --->
<cfinvoke component="#classpath#.cf_classes.dao.uploads" method="insertPhoto" returnvariable="success">
<cfinvokeargument name="fileName" value="#mypicture.SERVERFILE#"/>
<cfinvokeargument name="OutcomeID" value="#OutcomeID#"/>
</cfinvoke>
<cfset photoError = "Photo uploaded successfully"/>
<cfcatch type="any">
<cfset photoError = "There was an error uploading your photo.<br/> Please make sure it is a JPEG format."/>
</cfcatch>
</cftry>
No matter what, I just keep getting back the error message defined in the cfCatch. What are some good ways to troubleshoot something like this? Do any problems stand out to anyone?
Thanks for the help, I'm still relatively new to CF.
You're masking the exception that your cfcatch is catching by just setting a string in there. If you don't want to remove your exception handler, a quick and easy way to see what the underlying error is while you're still working on the code is to add:
<cfcatch><cfdump var="#cfcatch#"></cfcatch>
You may want to add an abort="true" to your cfcatch to stop processing of further code at that point which can mask your exception dump or cause it not to appear.
Putting cfcatch.message into a string that the user sees is not good practice as this may potentially result in information disclosure which can be a security risk (eg. if the message contains a file path on your server or similar)
Long term, if you're using Coldfusion Builder then you can also use the Coldfusion Debugger that is built in to step through your code and see where it is failing at the state of your variables at that point.

ColdFusion: get arguments of function which throws error in the onError-method of Application.cfc

I'm extending my errormanagement function which dumps a few scopes of variables and sends them via email to me. I'm using the onError-method in the Application.cfc for this case.
<CFDUMP var="#arguments.exception#" label="Error">
<CFDUMP var="#Application#" label="APPLICATION-Scope" />
<CFDUMP var="#form#" label="FORM-Scope">
<CFDUMP var="#url#" label="URL-Scope">
<CFDUMP var="#CGI#" label="CGI-Scope" />
<CFDUMP var="#session#" label="SESSION-Scope" />
<CFDUMP var="#variables#" label="VARIABLES-Scope" />
the onError has the exception as argument which I dump first in this example.... but how do I get the arguments of the function in which the error occured? For example if I call a UDF in my Application.cfc's onRequest-method like <CFSET giveMeMyScripts("javascript-file-1","javascript-file-2") /> Is this possible to get javascript-file-1 and javascript-file-2? Kind of super-arguments?
Thanks for any thoughts on this.
I'm not 100% sure, but you may be able to just dump arguments. It might depend how many functions deep you are.
Generally if you dump all the scopes and the exception, you have all the bits of information you need.
We do almost exactly what your doing and dump every scope in the application.cfc
Not sure you can do this without setting up a specific error trap inside the function. But if you are simply debugging and need to get past the error, copy the arguments into the request scope temporarily and then dump the request scope.