I have this function
<cffunction name="queryConvertForJQGRID" access="package" returntype="any" output="false">
<cfargument name="q" type="query" required="yes">
<cfargument name="page" type="numeric" required="no" default="1">
<cfargument name="rows" type="numeric" required="no" default="500">
<cfset var result = structnew()>
<cfset var rowStruct = structnew()>
<cfset var col = "">
<cfset result["page"] = arguments.page>
<cfset result["total"] = ceiling(arguments.q.TotalrecordCount/arguments.rows)>
<cfset result["records"] = arguments.q.TotalrecordCount>
<cfset result["rows"] = arraynew(1)>
<cfset queryDeleteColumn(arguments.q,'TotalrecordCount')>
<cfset queryDeleteColumn(arguments.q,'rowNum')>
<cfif server.coldfusion.productname eq 'lucee'>
<cfset columnLabels = QueryColumnArray(arguments.q)>
<cfelse>
<cfset columnLabels = arguments.q.columnList.listToArray()>
</cfif>
<cfloop query="#arguments.q#">
<cfset rowStruct = [:]><!--- Tada an ordered struct --->
<cfloop array="#columnLabels#" item="col">
<cfset rowStruct[col] = arguments.q["#col#"]>
</cfloop>
<cfset arrayappend(result.rows, rowStruct)>
</cfloop>
<cfreturn result />
</cffunction>
works perfect with lucee, but in coldfusion 2018, every row is showing the value as comma separated and all rows are in all rows. that is very weird
Screenshot
here is the screenshot https://prnt.sc/rcltqm
so i have like this
<cfset retJSON = queryConvertForjQGrid(local.returnQry, arguments.page, arguments.rows)>
<cfdump var="#retJSON#" abort>
and the structure is returned like this
https://prnt.sc/rcniba
i have written a web service which takes input parameters (json) from other application. i am just authenticating those values and returning the "http status codes and response" (using cfheader). For that I am trying the "RESTClient" in firefox extension. My problem is - It is running the "GET" method successfully but not the POST method.I guess the request is not even going to the server in POST method. See the screen shot below of both the request:
1. GET request
POST request
This is my CFC:
<cfcomponent rest="true" restpath="/AimsWeb"> <!--- REST Service--->
<cffunction name="AuthenticateUser" access="remote" httpmethod="POST" returntype="void">
<!---- Defining Arguments--->
<cfargument name="Username" type="string" required="Yes">
<cfargument name="Password" type="string" required="Yes">
<cfargument name="CustomerID" type="numeric" required="Yes">
<!---- Setting the Form Values (which we will get from AW+) and setting it to arguments passed--->
<cfset Form.CustomerID = arguments.CustomerID>
<cfset Form.Username = arguments.Username>
<cfset Form.Password = arguments.Password>
<!--- Take input json, parse it and set in in a variable --->
<cfscript>
record=deserializeJSON(
'{
"customerId": #Form.CustomerID#,
"userName": "#Form.userName#",
"password": "#Form.Password#"
}'
);
this.customerid = record.customerId;
this.userName = record.userName;
this.password = record.password;
</cfscript>
<cfquery name="AllUsers" datasource="#Application.GomDatasource#">
SELECT u.UserTypeID, u.UserID, u.CustomerID, u.UserName, u.Password, u.active, u.locked
FROM tblUsers u
WHERE u.CustomerID = <cfqueryparam cfsqltype="cf_sql_integer" value="#this.customerid#">
AND u.username = <cfqueryparam cfsqltype="cf_sql_varchar" value="#this.username#">
AND u.password = <cfqueryparam cfsqltype="cf_sql_varchar" value="#this.password#">
</cfquery>
<!--- This is to check whether provided parameters are valid by checking the same in the database--->
<cfset local.StatusStruct = StructNew()>
<cfif AllUsers.RecordCount AND (AllUsers.Active EQ 0 OR AllUsers.locked EQ 1)>
<cfheader statuscode="401" statustext="User Account is locked">
<cfelse>
<cfif this.customerid EQ "" OR this.username EQ "" OR this.password EQ "">
<cfheader statuscode="400" statustext="Insufficient Input. Please provide Customer ID, UserName and Password">
<cfelseif AllUsers.RecordCount AND this.CustomerId EQ AllUsers.CustomerID AND this.username EQ AllUsers.UserName AND this.password EQ AllUsers.Password>
<cfheader statuscode="200" statustext="Success">
<cfelseif AllUsers.CustomerID NEQ this.CustomerID>
<cfheader statuscode="400" statustext="Customer Id doesn't exist">
<cfelseif AllUsers.UserName NEQ this.UserName>
<cfheader statuscode="400" statustext="User not found">
<cfelseif AllUsers.Password NEQ this.password>
<cfheader statuscode="400" statustext="Invalid Password">
</cfif>
</cfif>
</cffunction>
</cfcomponent>
FYI a GET request has no request entity body because it is a GET request and the web server will generally ignore any body included in the request. I am surprised that ColdFusion provides a response since I don't see a GET method in your CFC.
The POST method is probably failing because the CFC is expecting a MIME type of application/form-url-encoded (your CFARGUMENTs) and you are posting application/json
Try breaking up into 2 functions, one which accepts application/json, one application/form-url-encoded
use the 'consumes' attribute in the CFFUNCTION to distinguish. They can both call a common function after this.
I have created a REST service in ColdFusion with a POST. It takes input json from other application, checks them in my DB and returns the http status code. Simple.
Calling it from RESTClient-FireFox Plus from POSTMAN-Chrome, my application says it's success/failure depending upon authentication, but RESTClient hangs continuing to show the progress bar and the button Abort.
The GET works perfectly fine though. Can anyone please help?
GET - Works fine.
POST - Does not work.
Here is my webservice(cfc):
<cfcomponent rest="true" restpath="/AimsWeb"> <!--- REST Service--->
<cffunction name="AuthenticateUser" access="remote" httpmethod="POST" returntype="void">
<!---- Defining Arguments--->
<cfargument name="Username" type="string" required="Yes">
<cfargument name="Password" type="string" required="Yes">
<cfargument name="CustomerID" type="numeric" required="Yes">
<!---- Setting the Form Values (which we will get from AW+) and setting it to arguments passed--->
<cfset Form.CustomerID = arguments.CustomerID>
<cfset Form.Username = arguments.Username>
<cfset Form.Password = arguments.Password>
<!--- Take input json, parse it and set in in a variable --->
<cfscript>
record=deserializeJSON(
'{
"customerId": "#Form.CustomerID#",
"userName": "#Form.userName#",
"password": "#Form.Password#"
}'
);
this.customerid = record.customerId;
this.userName = record.userName;
this.password = record.password;
</cfscript>
<cfdump var="#record#">
<cfquery name="AllUsers" datasource="#Application.GomDatasource#">
SELECT u.UserTypeID, u.UserID, u.CustomerID, u.UserName, u.Password, u.active, u.locked
FROM tblUsers u
WHERE
u.username = 'swapnil'
</cfquery>
<!--- This is to check whether provided parameters are valid by checking the same in the database --->
<cfset local.StatusStruct = StructNew()>
<cflog text="in struct" type="information">
<cfif AllUsers.RecordCount AND (AllUsers.Active EQ 0 OR AllUsers.locked EQ 1)>
<cfheader statuscode="401" statustext="User Account is locked">
<cflog text="account locked" type="information">
<cfelse>
<cfif this.customerid EQ "" OR this.username EQ "" OR this.password EQ "">
<cfheader statuscode="400" statustext="Insufficient Input. Please provide Customer ID, UserName and Password">
<cflog text="insufficient input" type="information">
<cfelseif AllUsers.RecordCount AND (this.CustomerId EQ AllUsers.CustomerID AND this.username EQ AllUsers.UserName AND this.password EQ AllUsers.Password)>
<cfheader statuscode="200" statustext="Success">
<cflog text="success" type="information">
<cfelseif AllUsers.CustomerID NEQ this.CustomerID>
<cfheader statuscode="400" statustext="Customer Id doesn't exist">
<cflog text="customer id not exist" type="information">
<cfelseif AllUsers.UserName NEQ this.UserName>
<cfheader statuscode="400" statustext="User not found">
<cflog text="user name not found" type="information">
<cfoutput>
user name not found
</cfoutput>
<cfelseif AllUsers.Password NEQ this.password>
<cfheader statuscode="400" statustext="Invalid Password">
<cflog text="invalid password" type="information">
</cfif>
</cfif>
</cffunction>
</cfcomponent>
Here is the JSON I am passing as a Body:
{
"customerId": 100,
"userName": "test",
"password": "xxxxx"
}
I have written a web-service in ColdFusion which returns message (success/failure) by checking the input values in the database.
To run the cfc, I am directly providing the arguments in the URL, like this:
http://localhost/AimsWeb/Authenticate2.cfc?method=AuthenticateUser&returnformat=json&CustomerID=1&username=xxx&password=xxxx
But when I run this page, it ends with an error like below:
This is my CFC:
<cfcomponent rest="true" restpath="/AimsWeb"> <!--- REST Service--->
<cffunction name="AuthenticateUser" access="remote" httpmethod="POST" returnFormat="JSON" returntype="json">
<!---- Defining Arguments--->
<cfargument name="Username" type="string" required="Yes">
<cfargument name="Password" type="string" required="Yes">
<cfargument name="CustomerID" type="string" required="Yes">
<!---- Setting the Form Values (which we will get from AW+) and setting it to arguments passed--->
<cfset Form.CustomerID = arguments.CustomerID>
<cfset Form.Username = arguments.Username>
<cfset Form.Password = Hash(arguments.Password)>
<cfif StructKeyExists (form, 'CustomerID') and StructKeyExists(form, 'UserName') and StructKeyExists (form, 'password')>
<cfquery name="AllUsers" datasource="#Application.GomDatasource#">
SELECT u.UserTypeID, u.UserID, u.CustomerID, u.UserName, u.Password
FROM tblUsers u
WHERE u.CustomerID = <cfqueryparam cfsqltype="cf_sql_integer" value="#Form.CustomerID#">
</cfquery>
<!--- This is to check whether provided parameters are valid by checking the same in the database--->
<cfset local.StatusStruct = StructNew()>
<cfif form.customerid EQ "" OR form.username EQ "" OR form.password EQ "">
<cfset local.StatusStruct['errorCode'] = 400>
<cfset local.StatusStruct['errorMessage'] = "Insufficient Input.">
<cfelseif AllUsers.RecordCount AND form.CustomerId EQ AllUsers.CustomerID AND form.username EQ AllUsers.UserName AND form.password EQ AllUsers.Password>
<cfset local.StatusStruct['errorCode'] = 200>
<cfset local.StatusStruct['errorMessage'] = "Success">
<cfelseif AllUsers.CustomerID NEQ form.CustomerID>
<cfset local.StatusStruct['errorCode'] = 400>
<cfset local.StatusStruct['errorMessage'] = "Customer Id doesn't exist">
<cfelseif AllUsers.UserName NEQ form.UserName>
<cfset local.StatusStruct['errorCode'] = 400>
<cfset local.StatusStruct['errorMessage'] = "User not found">
<cfelseif AllUsers.Password NEQ form.password>
<cfset local.StatusStruct['errorCode'] = 400>
<cfset local.StatusStruct['errorMessage'] = "Invalid Password">
</cfif>
<!--- Returning the status in JSON form--->
</cfif>
<cfreturn local.StatusStruct>
</cffunction>
</cfcomponent>
Can anyone help me please?
it worked. The returntype=json was not valid. I removed that line and it worked.
<cffunction name="AuthenticateUser" access="remote" httpmethod="GET" returnFormat="JSON">
Thanks ALL for your help.
My function calls the SendGrid API. It returns an Array + structure. I'm writing a function to return a CFQuery dataset.
Goal
I want to pass a deserialized data object to my function and get a query dataset.
Here is my working code and the output:
<cfparam name="variables.ddata" default="#structnew()#">
<!--- API Call Code here --->
<cfset arr = DESerializeJSON(returnStruct.Filecontent) />
<cfdump var="#arr#">
My code:
<cfset arrayit(arrobj= arr) >
<cfdump var="#variables.ddata#" >
<cffunction name="arrayit" access="public" returntype="void">
<cfargument name="arrobj" type="array" required="yes">
<cfset var arr=arguments.arrobj />
<cfloop from="1" to = "#arrayLen(arr)#" index="i">
<cfif isValid("string", arr[i])>
<cfset StructInsert(variables.ddata, i, arr[i]) />
</cfif>
<cfif isstruct(arr[i])>
<cfset structit(structobj = arr[i]) />
</cfif>
</cfloop>
</cffunction>
<cffunction name="structit" access="public" returntype="void" output="yes">
<cfargument name="structobj" type="any" required="yes">
<cfset stru = arguments.structobj />
<cfloop collection="#stru#" item="S">
<cfif isValid("string", stru[S])>
<cfset StructInsert( variables.ddata, S, stru[S]) />
</cfif>
<cfif isarray(stru[S])>
<cfset arrayit(arrobj = stru[S]) >
</cfif>
</cfloop>
</cffunction>
Result:
When I add this line in my function
<cfif isstruct(stru[S])>
<cfset variables.ddata = arrayit(arrobj = stru[S]) />
</cfif>
An error occurs:
Element type is undefined in a CFML structure referenced as part of an
expression. The error occurred on line 71.
** Full Code**
<cfsavecontent variable="returnStruct.Filecontent">
[{"date":"2016-04-05","stats":[{"type":"category","name":"5","metrics":{"blocks":1,"bounce_drops":0,"bounces":9,"clicks":4,"deferred":1,"delivered":1,"invalid_emails":8,"opens":4,"processed":1,"requests":1,"spam_report_drops":0,"spam_reports":1,"unique_clicks":3,"unique_opens":3,"unsubscribe_drops":0,"unsubscribes":9}}]}]
</cfsavecontent>
<cfset arr = DESerializeJSON(returnStruct.Filecontent) />
<cfloop from="1" to="#arrayLen(arr)#" index="i">
<cfif isValid("string", arr[i])>
<cfset StructInsert(variables.ddata, i, arr[i],true ) />
</cfif>
<cfif isstruct(arr[i])>
<cfsavecontent variable="rr">
<cfdump var="#arr[i]#" label="Line 48 ERROR" >
</cfsavecontent>
<cfset NotifyErrorAdmin(emailBody = "#rr#" ,emailsubject = "Line 48") />
<cfset structit(structobj = arr[i]) />
</cfif>
<cfif isarray(arr[i])>
<cfsavecontent variable="rr">
<cfdump var="#arr[i]#" label="Line 54 ERROR" >
</cfsavecontent>
<cfset NotifyErrorAdmin(emailBody = "#rr#" ,emailsubject = "Line 54") />
<cfset arrayit(arrobj = arr[i]) >
</cfif>
</cfloop>
</cffunction>
<cffunction name = "structit" access="public" returntype="void" output="yes">
<cfargument name = "structobj" type="any" required="yes">
<cfset stru = arguments.structobj />
<cfloop collection="#stru#" item="S">
<cfif isValid("string", stru[S])>
<cfset StructInsert( variables.ddata, S, stru[S],true) />
</cfif>
<cfif isarray(stru[S])>
<cfsavecontent variable="rr">
<cfdump var="#stru[S]#" label="Line 86 ERROR" >
</cfsavecontent>
<cfset NotifyErrorAdmin(emailBody = "#rr#" ,emailsubject = "Line 87") />
<cfset arrayit(arrobj = stru[S]) >
</cfif>
<cfif isstruct(stru[S])>
<cfsavecontent variable="rr">
<cfdump var="#stru[S]#" label="Line 97 ERROR" >
</cfsavecontent>
<cfset NotifyErrorAdmin(emailBody = "#rr#" ,emailsubject = "Line 97") />
<cfset structit(structobj = stru[S]) />
</cfif>
</cfloop>
</cffunction>
ERROR
Your UDF arrayit accepts an argument of type array but when that condition is true then a struct is being passed so, the error.
i.e.,
<cfif isStruct(stru[S])>
<!--- This means stru[S] is a struct --->
<cfset variables.ddata = arrayit(arrobj = stru[S])>
<!--- arrObj should be of type 'array' --->
</cfif>
So, it should be:
<cfif isStruct(stru[S])>
<cfset variables.ddata = structit(structobj = stru[S])>
</cfif>
But, the error for this case will be different than that you have added.
Additionally,
StructInsert() takes an optional argument allowoverwrite which is by default false and according to docs:
if key exists and allowoverwrite = "False", ColdFusion throws an
exception.
I just did it! :) just wanted to share my project with you guys also hope it will help someone else also...
Request if you guys find anything you feel I can improve please share.
Special Thanks for response on my post. #Beginner & #Leigh
API Call Json Return: 1
<cfsavecontent variable="returnStruct.Filecontent">
[{"date":"2016-04-05","stats":[{"type":"category","name":"5","metrics":{"blocks":1,"bounce_drops":0,"bounces":9,"clicks":4,"deferred":1,"delivered":1,"invalid_emails":8,"opens":4,"processed":1,"requests":1,"spam_report_drops":0,"spam_reports":1,"unique_clicks":3,"unique_opens":3,"unsubscribe_drops":0,"unsubscribes":9}}]}]
</cfsavecontent>
<cfset arr = DESerializeJSON(returnStruct.Filecontent) />
CFC : 2
<cfcomponent>
<cfparam name="variables.qryclsvar" default="" type="any"/>
<cfparam name="variables.qryclsvarfg" default="true" type="any"/>
<cffunction name="APItoquery" access="public" returntype="any">
<cfargument name = "APIobj" type="any" required="yes">
<cfset var vAPIobj = arguments.APIobj />
<cfset var APIDATA = structnew() />
<cfset var APIDATAqr = "" />
<cftry>
<cfloop from="1" to="#arrayLen(vAPIobj)#" index="jj">
<cfif isarray(vAPIobj[jj])>
<cfset APIDATA = arrayit(structobj = vAPIobj[jj] ,datastruct = APIDATA) />
</cfif>
<cfif isstruct(vAPIobj[jj])>
<cfset APIDATA = structit(structobj = vAPIobj[jj],datastruct = APIDATA) />
</cfif>
<cfif NOT StructIsEmpty(APIDATA)>
<!--- Add in query object --->
<cfset APIDATAqr = structtoquery(structobj= APIDATA) />
<cfelse>
<cfset APIDATAqr ="NO Data Found!" />
</cfif>
</cfloop>
<cfcatch>
<cfdump var="#cfcatch#" label="APItoquery">
</cfcatch>
</cftry>
<cfreturn APIDATAqr>
</cffunction>
<cffunction name = "arrayit" access="public" returntype="any">
<cfargument name = "arrobj" type="any" required="yes">
<cfargument name = "datastruct" type="any" required="yes" >
<cfset var arr = arguments.arrobj />
<cfset var arrdata = arguments.datastruct />
<cftry>
<cfloop from="1" to="#arrayLen(arr)#" index="i">
<cfif ArrayContains(arr, i) >
<cfset StructInsert(arrdata, i, arr[i],true ) />
</cfif>
<cfif isarray(arr[i])>
<cfset arrdata = arrayit(arrobj = arr[i] ,datastruct = arrdata) >
</cfif>
<cfif isstruct(arr[i]) >
<cfset stdata = structit(structobj = arr[i],datastruct = arrdata) />
</cfif>
</cfloop>
<cfcatch>
<cfdump var="#cfcatch#" label="arrayit">
</cfcatch>
</cftry>
<cfreturn arrdata>
</cffunction>
<cffunction name = "structit" access="public" returntype="any" output="yes">
<cfargument name = "structobj" type="any" required="yes">
<cfargument name = "datastruct" type="any" required="yes">
<cfset var stru = arguments.structobj />
<cfset var stdata = arguments.datastruct />
<cftry>
<cfloop collection="#stru#" item="S">
<cfif isarray(stru[S])>
<cfset stdata = arrayit(arrobj = stru[S] ,datastruct = stdata) >
<cfelseif isstruct(stru[S]) >
<cfset stdata = structit(structobj = stru[S],datastruct = stdata) />
<cfelse>
<cfset StructInsert( stdata, S, stru[S],true) />
</cfif>
</cfloop>
<cfcatch>
<cfdump var="#cfcatch#" label="structit">
</cfcatch>
</cftry>
<cfreturn stdata>
</cffunction>
<cffunction name = "structtoquery" access="public" returntype="any" output="yes">
<cfargument name = "structobj" type="any" required="yes">
<cfset var vstructobj = arguments.structobj />
<cfset var cols = StructKeyList(vstructobj)>
<cfset var colstyp = "">
<cftry>
<cfif variables.qryclsvarfg EQ true>
<cfloop from="1" to="#listlen(cols,',')#" index="L">
<cfset colstyp = ListAppend(colstyp,"VarChar",",")>
</cfloop>
<!--- Create a new query. --->
<cfset variables.qryclsvar = queryNew(
'#cols#',
'#colstyp#'
)>
<cfset variables.qryclsvarfg = false>
</cfif>
<cfset QueryAddRow(variables.qryclsvar, 1)>
<cfloop collection="#vstructobj#" item="sd">
<cfset QuerySetCell(variables.qryclsvar, "#sd#", vstructobj[sd])>
</cfloop>
<cfcatch>
<cfdump var="#cfcatch#" label="structit">
</cfcatch>
</cftry>
<cfreturn variables.qryclsvar>
</cffunction>
</cfcomponent>
CFM : 3
<cfset sgObj = createobject("component","cfc.mycfc") />
<cfset mystruct = sgObj.APItoquery(APIobj= arr1) >
<cfdump var="#mystruct#" label="mystruct">
MA ! ....