Return JSON data in response in ColdFusion - json

I'm working in ICIMS API. I need to return JSON data and some specific data in header in a cfm page call by ICIMS server.
Here is the response should be:
Response to the Work Flow Status Change PUSH event to the platform:
HTTP/1.1 303 See Other
Location: http://xx.xx.xx.xx:8085/selectpackage?systemHash=101
Content-Type: application/json
{
"userMessage":"Confirm or modify package.",
}
Thanks in advance.
Answer:
> <cfset contentString = '{"userMessage": "Confirm or modify package."}'
> />
>
> <cfheader name="Location"
> value="http://xx.xx.xx.xx:8085/selectpackage?systemHash=101" />
> <cfcontent type="application/json" variable="#toBinary( toBase64( contentString ) )#" />

<cfheader
statusCode = "303"
statusText = "See Other">
<cfheader
name="Location"
value="http://xx.xx.xx.xx:8085/selectpackage?systemHash=101">
<cfheader
name="Content-Type"
value="application/json">
<cfset foo = structNew()>
<cfset foo["userMessage"] = "Confirm or modify package.">
<cfoutput>#serializeJSON(foo)#</cfoutput>

Related

Azure APIM - XML to JSON Conversion

I am trying to figure out how to properly use the XML to JSON conversion in the Azure APIM Policy Editor. I've seen dozens of examples where all that's identified is this:
<xml-to-json kind="direct" apply="always" consider-accept-header="false" />
However, I cannot find the appropriate place within my policy to place the code to make it do what I'm expecting. Here is my Outbound policy, which is where I am looking to use this:
<outbound>
<base />
<choose>
<when condition="#(context.Response.StatusCode < 400)">
<set-body template="liquid">
{% if body.envelope.body.GetProjectsByQueryResponse.GetProjectsByQueryResult %}"{{body.envelope.body.GetProjectsByQueryResponse.GetProjectsByQueryResult | Replace: '\r', '\r' | Replace: '\n', '\n' | Replace: '([^\\](\\\\)*)"', '$1\"'}}"{% else %} null {% endif %}
</set-body>
</when>
<otherwise>
<set-variable name="old-body" value="#(context.Response.Body.As<string>(preserveContent: true))" />
<!-- Error response as per https://github.com/Microsoft/api-guidelines/blob/master/Guidelines.md#7102-error-condition-responses -->
<set-body template="liquid">{
"error": {
"code": "{{body.envelope.body.fault.faultcode}}",
"message": "{{body.envelope.body.fault.faultstring}}"
}
}
</set-body>
<choose>
<when condition="#(string.IsNullOrEmpty(context.Response.Body.As<JObject>(preserveContent: true)["error"]["code"].ToString()) && string.IsNullOrEmpty(context.Response.Body.As<JObject>(preserveContent: true)["error"]["message"].ToString()))">
<set-body>#{
var newResponseBody = new JObject();
newResponseBody["error"] = new JObject();
newResponseBody["error"]["code"] = "InvalidErrorResponseBody";
if (string.IsNullOrEmpty((string)context.Variables["old-body"]))
{
newResponseBody["error"]["message"] = "The error response body was not a valid SOAP error response. The response body was empty.";
}
else
{
newResponseBody["error"]["message"] = "The error response body was not a valid SOAP error response. The response body was: '" + context.Variables["old-body"] + "'.";
}
return newResponseBody.ToString();
}</set-body>
</when>
</choose>
</otherwise>
</choose>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<xml-to-json kind="direct" apply="always" consider-accept-header="false" />
</outbound>
As you can see I've tried placing the conversion line at the very end of the outbound policy, but it's not doing what I expect; I still have an xml document returned.
Any help here in understanding how to revise my policy to work would be wonderful.

Connect to remote API using ColdFusion cfhttp

I am trying to connect to the emma api using ColdFusion. Using the below code. Trying to get a listing of all members in an account as per api docs doing the below. I keep getting status code of 404 on the below call. Any ideas on what I am missing here?
<cfset account_id= '123'/>
<cfset public_key = 'abc'/>
<cfset private_key = 'xyz' />
<cfset the_url = 'https://app.e2ma.net/#account_id#/members/' />
<cfhttp url="#the_url#" method="get" result="Results" timeout="999">
<cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded" />
<cfhttpparam type="header" name="Accept" value="application/json" />
<cfhttpparam type="header" name="public_api_key" value="#public_key#" >
<cfhttpparam type="header" name="private_api_key" value="#private_key#" >
</cfhttp>
<cfdump var="#Results#"/>
Here are the results of the cfdump:
It looks like you're using the wrong endpoint. In their documentation they say the following:
The endpoint for all of our API calls is https://api.e2ma.net/
In your code you're using app.e2ma.net, this should be api.e2ma.net instead.
Also the path for the URL you're requesting doesn't include a trailing slash in their documentation (GET /#account_id/members is what they have). You may also want to update that.

POSTing Nested JSON in AngularJS [400 error]

Part of my HTML
<div>House Details:
<input type ="number" ng-model="house.totalArea" placeholder="total_area">
<input type="number" ng-model="house.cost" placeholder="Cost">
</div>
<div>Address:
<input type="text" ng-model="house.address.state" placeholder="state">
<input type="text" ng-model="house.address.city" placeholder="city ">
</div>
Angular:$scope.house = {};
$scope.house.address = {};
$scope.processRentForm = function () {
console.log($scope.house);
$http.post("http://localhost:8080/Property101/house/addHouse", $scope).
error(function (data, status, headers, config) {alert("Submit failed!!");
Code works fine for just $scope.house but
I'm getting a 400 eror ( syntactically incorrect) for nested JSON which is forming as
Object {address: Object, totalArea: 1000}
I have a Address class inside a House class on server side which have the similar no./names of parameters as the JSON I'm trying to send.
Some of the examples at SO have "house.address.state" syntax.
I'm new angular, any help would be appreciated.
Before sending the request JSON onto server side do the following 2 steps,
1) var reqObj = JSON.stringify($scope.house);
2) var requestJson = JSON.parse(reqObj)
Now send the requestJson as request. It should work.

Why is my urlfetchapp Post not working and throwing a 500 response code

I'm writing a google apps script that is supposed to login to a website and then crawl the site and perform different actions.
The script successfully authenticates the website and completes several get methods, but when it tries to do a Post on a PostSelect drop-down box I'm getting a 500 response code.
My script follows:
function getRaceData(browser) {
var eId = "72370";
var selectNbr = "17";
var url = "http://tnetwork.trakus.com/tnet/t_Recap.aspx?EventID=" + eId;
var options = {
"method": "get",
// Set the cookies so that we appear logged-in
"headers": {
"Cookie": browser.cookie
},
"followRedirects" : false
}
var response = UrlFetchApp.fetch(url, options);
var html = response.getContentText();
var code = response.getResponseCode();
browser.html = html;
Utilities.sleep(1000);
var url = "http://tnetwork.trakus.com/tnet/t_Recap.aspx";
var payload = {"EventIDHidden" : eId, "PostSelect" : selectNbr};
var header = {"Cookie" : browser.cookie};
var options = {"method" : "post","headers" : header,"payload":payload,"followRedirects" : false};
Logger.log(UrlFetchApp.getRequest(url, options));
**var response = UrlFetchApp.fetch(url, options);** //This line causes 500 response code.
var html = response.getContentText();
var code = response.getResponseCode();
Logger.log(html);
}
Here is the error message I receive:
Request failed for http://tnetwork.trakus.com/tnet/t_Recap.aspx returned code 500. Truncated server response: <html>
<head>
<title>Runtime Error</title>
<style>
body {font-family:"Verdana";font-weight:normal;font-size: .7em;... (use muteHttpExceptions option to examine full response) (line 190, file "PostTest")
Update: Here is the Request Header that I was able to inspect by using Google Chrome Developer Tool Network selection:
POST /tnet/t_Recap.aspx HTTP/1.1
Host: tnetwork.trakus.com
Connection: keep-alive
Content-Length: 23079
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://tnetwork.trakus.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://tnetwork.trakus.com/tnet/t_Recap.aspx?EventID=72370
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: ASP.NET_SessionId=ayek3u55dsapvxe2t5kio0a3; __utma=260442568.815817400.1426544670.1426555405.1426631681.3; __utmc=260442568; __utmz=260442568.1426544670.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); userCredentials=username=MyUserName; .ASPXAUTH=D637CD472308F766FA8D267B85D8018028FC7981748D6B3EE9DC43166998E1F7F5A9B2A676CB1FD67560B86F40A633C4DDAAE6B13BBD0B07728E00E00977F271ABD5CC74D9AD88405CB7DD04F43F5EDDEF84EAAA14E5A3A638A744B0B76EA2FFEF2434A393E5FD699416FEA1A4EF0488671D82E4; __utma=190106350.902310224.1426544678.1426631684.1426643061.5; __utmb=190106350.3.10.1426643061; __utmc=190106350; __utmz=190106350.1426544678.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Also here is what I get when from logging the my UrlFetchApp.getRequest(url, options) function.
{headers{Cookie=ASP.NET_SessionId=zv2o2o55tgl2ctbse52vwln1;userCredentials=username=MyUserName;.ASPXAUTH=9980822DFE22641E55F3545CAEAFA748A39AC05A69F74A67BC656078C192769BB74A0B6F000241B36A670362019F5D14DCD1A6FD9E43718B5BC8AD89E9037DBEA1CE2A012AFFFC704D35C71EB82DAC18C644F0EBA34992604ABF2680DE97098C8BE3CB0BAEADD51C65E2EB0C8851C9E151337EA4, X-Forwarded-For=71.168.117.91}, useIntranet=false, followRedirects=false, payload=PostSelect=17&EventIDHidden=72370, method=post, validateHttpsCertificates=true, contentType=application/x-www-form-urlencoded, url=http://tnetwork.trakus.com/tnet/t_Recap.aspx}
I believe my syntax is correct and I've been able to pass the cookie successfully with all of the prior get statements and for the Login Post, so I'm not sure why this Post is failing. If anyone has any thoughts or has come across something similar, I'd appreciate your input
Update: I been review the page source a bit more carefully and wanted to share the following:
That page has a very large form that appears to include hidden inputs other than the ones in my Post statement (See below). Additionally, the Select statement has an onChange="UpdatePostView().
The UpdatePostView() is fairly straight forward:
function UpdatePostView()
{
document.TChartForm.submit();
}
Additional inputs include
<form name="TChartForm" method="post" action="t_Recap.aspx" id="TChartForm">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="eBDduN+CtRzqAG6KZjuiZQhrTRokT2cqgaabq7fy3oSZaeE+O83K0QTLMCessWWC27snsJrG607bicynkgi9j1+4a++Gpz8+S5CeD9hhjzEEH8NuJUOtgPDOV5QFkqNrGVX4g+1YehwD+A5V7K5o+j5zva1cABIEhbHoxAqKrETpZgNVDjpZWTc+Hl4NaG1aTGpARvzUTgU23CvtxwYrIAH2CVuDHeqMTo0B9aOB73e4liFQtMnj/64ETSf2eGvbgmBLKaPHDxDrRCjMRLBinWRn94lLF6Cf3ZUVoQTMU4IgpQ==" />
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="696C68DE" />
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="pv3ODePltFyNx0vx4zFN/4siIO4psfHIMLofolP8T27GF4kko1Ol7wQaPQ0nuAtGCoANyMCeHmV0ecBuv/CGuv4YF2jZSIQmPtNFmSpDEh/EJvyVxljXY2d+gv8=" />
<input type="hidden" name="EventIDHidden" id="EventIDHidden" value="72370" />
<input type="hidden" id="SessionUser" value="MyUserName" />
<input type="hidden" id="SessionAccessStr" value="MyUserName" />
<div id="DisplayArea"><table class="headLinks" align="center" width="97%" cellpaddiong="0" cellspacing="0"><tr><td width="50%"><div align="left"><a style="white-space:nowrap;" href="t_RaceDay.aspx?VenueID=24&Type=TBRED&Date=03/01/2015">«««More Aqueduct Races on 03/01/2015</a></div><br /><div align="left"><a href="previous.html" onClick="history.back();return false;">«««Previous Page
</a></div><p /></td><td valign="top"><div align="right"><b>
T-Net Member: myTnetMemberName </b></div></td></tr></table><table align="center" class="topThreeContainer" cellpadding="2" cellspacing="0"><tr align="center" class="topThreeTitle"><td style="white-space:nowrap">Track</td><td style="white-space:nowrap">Official Results</td><td style="white-space:nowrap">Trakus Times</td></tr><tr><td><img src="images/TrackLogos/24.gif" /></td><td valign="top"><table cellpadding="2"><tr class="topThreeHead"><td><div style="width:40px;">Win</div></td><td><div style="width:40px;">Place</div></td><td><div style="width:40px;">Show</div></td></tr><tr><td><img width="30" height="27" src="images/HorseRacingTiles/Trakus/3.gif" /></td><td><img width="30" height="27"
additional form data omitted due to space constraints....
<select runat="server" autopostback="true" style="width:250px" id="PostSelect" onChange="UpdatePostView();" name="PostSelect"><option value="0">Race Summary</option><option value="2">1/16 Mile</option><option value="3">1/8 Mile</option><option value="4">3/16 Mile</option><option value="5">1/4 Mile (POC)</option><option value="6">5/16 Mile</option><option value="7">3/8 Mile</option><option value="8">7/16 Mile</option><option value="9">1/2 Mile (POC)</option><option value="10">9/16 Mile</option><option value="11">5/8 Mile</option><option value="12">11/16 Mile</option><option value="13">3/4 Mile (POC)</option><option value="14" selected="">13/16 Mile</option><option value="15">7/8 Mile (POC)</option><option value="16">15/16 Mile</option><option value="17">1 Mile (Finish)</option></select>
additional form data omitted due to space constraints....
Race Notes: </div></td></tr><tr><td align="right" colspan="2"><div align="right" style="font-size:8px;font-weight:bold;">Updated 3/1/2015 6:29:10 PM GMT
</div></td></tr></table></div></form>
Given this new information, I have a couple additional questions:
Do I need to add the other hidden inputs to my payload or are they embedded in the Html and therefore get submitted anyway.
Does the urlfecthapp command fire the onchange event or do I have to do something special to fire that.
What is the role of the ViewState, ViewStateGenerator and EventValidation. These were present in the login form, but I did not need to include them in the payload to login successfully.
Here is my full script if anyone would like to try it and see the results for themselves.
Full Script
Thanks again.

How to format a json feed from coldfusion to jquery fullcalendar?

I am trying to get a json feed working for the jquery Full Calendar plugin but I am not having much luck. The data I get back from coldfusion is not formatted correctly (at least that is my guess). Here is what I am getting back:
{"COLUMNS":["TITLE","START","END","REQUEST_TYPE_ID"],"DATA":[["duration of a VTC ","2012-03-15T12:00:00Z","2012-03-15T15:00:00Z",1],["a new vtc overlap","2012-03-15T11:45:00Z","2012-03-15T14:15:00Z",1]]}
I am pretty sure full calendar does not know how to read this data type. So the question is, can I get CF to pass back the data in a format that full calendar will accept? Is there something else going on here?
Here is my component:
<cfquery datasource="#arguments.dsn#" name="eventlist">
select title, to_char(start_time,'YYYY-MM-DD')||'T'||to_char(start_time,'HH24:MI:SS')||'Z' as "start",
to_char(start_time,'YYYY-MM-DD')||'T'||to_char(start_time + (duration/1440),'HH24:MI:SS')||'Z' as "end", request_type_id
from ((request r join event_schedule es on es.request_id = r.id)left join location_ref loc on loc.location_id = r.location_id)
where site_id = <cfqueryparam value="#arguments.site_id#" cfsqltype="cf_sql_varchar" />
and request_type_id = <cfqueryparam value="#arguments.evnttype#" cfsqltype="cf_sql_varchar" />
and start_time between to_date('#sdate#', 'mon dd yyyy') and to_date('#edate#', 'mon dd yyyy')
</cfquery>
and the return format is json.
returnformat="json"
Any ideas?
Thanks!
You need to format your data for the plugin to work. It needs to be an array of Event Objects http://arshaw.com/fullcalendar/docs/event_data/Event_Object/
So you need to loop through your query and create an array of structs with the keys specified on the documentation in the above link.
You will need to use array notation as JavaScript is case-sensitive for variable names and CF likes to make the keys in structs uppercase by default.
So do this:-
<cfset myStruct["id"] = 1>
Instead of:-
<cfset myStruct.id = 1>
I hope that helps.
I created a CFC that returns jSon based on the date passed;
My CFC broken down:
<cfcomponent>
<cffunction name="LoadCalendarData" access="remote" output="false" returntype="Any" returnformat="JSON">
<cfargument name="DEPTID" type="any" required="false" />
<cfargument name="STAFFCLASSID" type="any" required="false" />
<cfargument name="start" type="date" required="false" />
<cfargument name="end" type="date" required="false" />
<cfset arguments.start=#DateFormat(DateAdd("s", arguments.start, "January 1 1970 00:00:00"), "mmmm dd, yyyy")#/>
<cfset arguments.end=#DateFormat(DateAdd("s", arguments.end, "January 1 1970 00:00:00"), "mmmm dd, yyyy")#/>
<cfinvoke component="DataStore" method="Calendar_LU" returnvariable="qGetCalendar" DEPTID="#arguments.deptid#" STAFFCLASSID="#arguments.STAFFCLASSID#" START="#arguments.start#" END="#arguments.end#" />
I tranlate the arguments of the start date and end date in to something fullcalendar can use then I start to build by looping the data based on the information returned. next I break down the dates and times so I can pass it back to fullCalendar.
<cfset CalendarData=[] />
<cfset CalData = arraynew(2) />
<cfloop query="qGetCalendar">
<cfset sd = #dateformat(LEAVESTARTDATE,'dd')# />
<cfset sm = #dateformat(LEAVESTARTDATE,'mm')# />
<cfset sy = #dateformat(LEAVESTARTDATE,'yyyy')# />
<cfset sh = #timeformat(LEAVESTARTDATE,'HH')# />
<cfset si = #timeformat(LEAVESTARTDATE,'mm')# />
<cfset ed = #dateformat(LEAVEENDDATE,'dd')# />
<cfset em = #dateformat(LEAVEENDDATE,'MM')# />
<cfset ey = #dateformat(LEAVEENDDATE,'yyyy')# />
<cfset eh = #timeformat(LEAVEENDDATE,'HH')# />
<cfset ei = #timeformat(LEAVEENDDATE,'mm')# />
<cfset event=structNew() />
<cfset event['title']='#Left(ListLast(FULLNAME,","),1)#. #REReplace(ListFirst(FULLNAME,","),"'","")#' />
<cfset event['start']='#sy#-#sm#-#sd# #sh#:#si#' />
<cfset event['end']='#ey#-#em#-#ed# #eh#:#si#' />
<cfset event['textColor']='##330000'/>
<cfset event['backgroundColor']=STATUSColor />
<cfset event['url']=clickablePath />
<cfset arrayAppend(CalendarData,event)/>
</cfloop>
<cfreturn calendarData />
</cffunction>
in the script where fullCalendar is called I use this to call the CFC
eventSources: [{url:'CFCs/Holidays.cfc?Method=LoadCalendarHolidays'},{url:'CFCs/CalendarDataRemote.cfc?Method=LoadCalendarData&DEPTID=<cfoutput>#deptid#</cfoutput>&STAFFCLASSID=<cfoutput>#STAFFCLASSID#</cfoutput>'}],
As you can see I added another CFC call to pull in the our holidays so you can load more than one calendars data. Hope this helps
You also need to make sure the keywords are lowercase... fullCalendar like javascript is case sensitive so you need start, end etc.
OOOPS just read the end of baynezy answer mentions this please disregard.