How can I create output from a CFFUNCTION with type "application/json"?

1.1k Views Asked by At

I have a cfc that creates an output string containing JSON. The payload is fine but the person receiving it tells me that the data is coming in as text/html and his program doesn't recognize it as valid because it needs to be application/json.

So I modified the parameters in my CFFUNCTION statement and I have built a small test program that says:

 <cffunction name="Test" httpmethod="get" returntype="JSON" output="yes" access="remote">
    <cfset JSON='{"Test": "A"}'>
    <cfreturn JSON>
    </cffunction>

But when I execute this cfc remotely, I get the error message "The value returned from the Test function is not of type JSON".

This should be easy but I can't see what I need to do to return a JSON string with the application/json type.

1

There are 1 best solutions below

2
On BEST ANSWER

Your first issue will be that returntype="JSON" - it looks like you're confusing returntype and returnformat. There are various ways of achieving what you're trying to do, eg each of these would return the same result:

<!--- Function returns a struct, ask CF to convert it to JSON using returnformat: --->
<cffunction name="Test2" returntype="struct" returnformat="JSON" output="false" access="remote">
    <cfset var myStruct={"Test"="A", "foo"="bar"} />
    <cfreturn myStruct />
</cffunction>

<!--- Function uses a struct, but serializes as a JSON string before returning --->
<cffunction name="Test3" returntype="string" returnformat="plain" output="false" access="remote">
    <cfset var myStruct={"Test"="A", "foo"="bar"} />
    <cfreturn SerializeJSON(myStruct)>
</cffunction>

<!--- Same as above but another variation of struct notation. 
    Note that most CF environments will convert unquoted key names to uppercase 
    unless you enable serialization.preserveCaseForStructKey at application or CF Admin level --->
<cffunction name="Test4" returntype="string" returnformat="plain" output="false" access="remote">
    <cfset var myStruct=structNew() />
    <cfset myStruct['Test'] = "A" />
    <cfset myStruct['foo'] = "bar" />
    <cfreturn SerializeJSON(myStruct) />
</cffunction>

<!--- Manually build the JSON string yourself from scratch, beware of encoding/escaping issues --->
<cffunction name="Test5" returntype="string" returnformat="plain" output="false" access="remote">
    <cfset var myJSONString='{"Test":"A","foo":"bar"}' />
    <cfreturn myJSONString />
</cffunction>

Note that the above alone will not set the content type response header to application/json, if your caller actually cares about that, then you'll need something like: <cfheader name="Content-Type" value="application/json; charset=utf-8" /> ...but the The value returned from the Test function is not of type JSON error you refer to is a CF runtime error, not a browser/ajax error. The full text of that error would normally be:

The value returned from the Test function is not of type JSON. If the component name is specified as a return type, it is possible that either a definition file for the component cannot be found or is not accessible.