Salesforce - Data type for webservice response - web-services

Im trying to execute/consume a webservice and wondering if I am using the correct data type to return the results. String seems to work, but I receive an empty string. The service should be returning a simple string value without XML. There is a working version written in JS below, I have been asked to recreate it in Apex.
JS version (Working) - executed when a button is clicked
{!REQUIRESCRIPT("/soap/ajax/24.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/24.0/apex.js")}
var xfolder = "TestFolder"
var parentid = "22K22"
var myvar = sforce.apex.execute("myWS","invokeWs", {folderName:xfolder,ObjectID:parentid});
window.alert('LiveLink folder created: ' + myvar);
APEX version (not working)
public with sharing class myTest {
public String getWSXMLResult() {
String tmpFolderName2 = 'TestFolder';
String tmpObjectID2 = '22K22';
String myWSXMLResult = myWS.invokeWs(tmpFolderName2,tmpObjectID2);
System.debug('XIXWS|' + myWSXMLResult);
return myWSXMLResult;
}
}
One thing I just noted while typing this out. I didn't specify the argument names for invokeWs, just the values..do I need to specify those values in the call to the WS? Such as..
myWS.invokeWs(folderName=tmpFolderName2,ObjectID=tmpObjectID2); -- this errors out btw
Thanks again everyone.

Related

How to build a Postman url query with Pre-request Scripts

I'm trying to use a pre-request script to build out a request object based on data pulled from a CSV file. The problem is that the request seems to be set in stone prior to the pre-request script being run. That would seem to make this a mid-request script almost rather than a pre-request.
My code is as follows:
if(ipList === undefined) ipList = "1.2.3.4,2.3.4.5,123.234.345.465";
let ips = ipList.split(',');
let queryArray = [];
for( i=0; i<ips.length; i++){
queryArray.push({ "key": "ip", "value": ips[i] });
}
console.log(queryArray);
pm.request.url.query = queryArray;
console.log(pm.request);
When I hardcode a url query variable in the request to equal 4.3.2.1, the pm.response.url object like this:
pm.request.url.query[0] = {key:"ip", value:"4.3.2.1"}
Note that the url.query[0] part of the object matches the parameter in the actual get request.
When I change the value of pm.request.url.query to equal the new query array, however as you can see here, the query array is set correctly, but the parameters are not appended to the request URL.
So unless I'm doing something wrong, it appears that the request is immutable even to the pre-request scripts.
So my question is this:
Is there a way to modify the url params of a request prior to making the request?
BTW: I know that is might seem odd to have multiple params with the same key in a query, but that's the way this API works and hard coding multiple ip addresses in the query works just fine.
You could just assign a new value to pm.request.url.
Here I had some query params already in the URL, which I had to edit:
const urlSplit = request.url.split('?');
const paramsString = urlSplit[1]; // the second part actually represents the query string we need to modify
const eachParamArray = paramsString.split('&');
let params = {};
eachParamArray.forEach((param) => {
const key = param.split('=')[0];
const value = param.split('=')[1];
Object.assign(params, {[key]: value});
});
params.bla = params.bla + 'foobar';
newQueryString = Object.keys(params).map(key => key + '=' + params[key]).join('&');
pm.request.url = urlSplit[0] + '?' + newQueryString;
In the end, I just constructed a new URL, using the first part of the previous one & the query string with the edited bla parameter.
This seemed to work for me--it didn't change what the UI shows the query string is, but it changed what the actual request was (looking at the console log)
pm.request.url.addQueryParams(["a=1", "b=2"])
pm.request.url.query.remove("b")
I have some parameters called "script_loginAs" etc... named such that people on my team know the parameter is evaluated and not sent.

Salesforce APEX Unit Test Error with REST Services / Error at SELECT of Case Object

I've succeeded to successfully construct a REST API using APEX language defined with an annotation: #RestResource.
I also wrote a matching Unit test procedure with #isTest annotation. The execution of the REST API triggered by a HTTP GET with two input parameters works well, while the Unit Test execution, returns a "null" value list resulting from the SOQL query shown below:
String mycase = inputs_case_number; // for ex. '00001026'
sObject[] sl2 = [SELECT Id, CaseNumber FROM Case WHERE CaseNumber = :mycase LIMIT 1];
The query returns:
VARIABLE_ASSIGNMENT [22]|sl2|[]|0x1ffefea6
I've also tried to execute it with a RunAs() method (see code below), using a dynamically created Salesforce test user, not anonymous, connected to a more powerful profile, but still receiving a "null" answer at the SOQL query. The new profile defines "View All" permission for Cases. Other SOQL queries to objects like: "User" and "UserRecordAccess" with very similar construction are working fine, both for REST APEX and Test APEX.
Is there a way to configure an access permission for Unit test (#isTest) to read the Case object and a few fields like: Id and CaseNumber. Is this error related to the "Tooling API" function and how can we fix this issue in the test procedure?
Code attachment: Unit Test Code
#isTest
private class MyRestResource1Test {
static testMethod void MyRestRequest() {
// generate temporary test user object and assign to running process
String uniqueUserName = 'standarduser' + DateTime.now().getTime() + '#testorg.com';
Profile p = [SELECT Id FROM Profile WHERE Name='StandardTestUser'];
User pu = new User(Alias='standt',Email='standarduser#testorg.com',LastName='testing',EmailEncodingKey='UTF-8',LanguageLocaleKey='en_US',LocaleSidKey='en_US',ProfileId=p.Id,TimeZoneSidKey='America/New_York',UserName=uniqueUserName);
System.RunAs(pu) {
RestRequest req = new RestRequest();
RestResponse res = new RestResponse();
req.requestURI = '/services/apexrest/sfcheckap/';
req.addParameter('useremail','testuserid#red.com');
req.addParameter('casenumber','00001026');
req.httpMethod = 'GET';
RestContext.request = req;
RestContext.response = res;
System.debug('Current User assigned is: ' + UserInfo.getUserName());
System.debug('Current Profile assigned is: ' + UserInfo.getProfileId());
Test.startTest();
Map<String, Boolean> resultMap = MyRestResource1.doGet();
Test.stopTest();
Boolean debugflag = resultMap.get('accessPermission');
String debugflagstr = String.valueOf(debugflag);
System.assert(debugflagstr.contains('true'));
}
}
}
Found a solution path by using: #isTest(SeeAllData=true)
See article: "Using the isTest(SeeAllData=true) Annotation"
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_seealldata_using.htm

Regex For Work Items in Team Services API

I'm retrieving a list of Work Items using the VSTS API and would like to display them on my web app. I can successfully return a list of the work items in the format below:
{"count":1,"value":[{"id":246,"rev":4,"fields":{"System.Id":246,"System.State":"New","System.Title":"test1"},"url":"https://example.visualstudio.com/_apis/wit/workItems/246"}]}
I have tried a regular expression to get the values from this HTTP response with the following code:
HttpResponseMessage getWorkItemsHttpResponse = client.GetAsync("_apis/wit/workitems?ids=" + ids + "&fields=System.Id,System.Title,System.State&asOf=" + workItemQueryResult.asOf + "&api-version=2.2").Result;
if (getWorkItemsHttpResponse.IsSuccessStatusCode)
{
result = getWorkItemsHttpResponse.Content.ReadAsStringAsync().Result;
// Regular expression to extract work item values to display
string parseWI = result.ToString();
var match = Regex.Match(parseWI, "\"System.ID\": (.*)");
workItemsToDisplay = (match.Groups[1].Value);
}
}
}
}
return workItemsToDisplay;
}
This is refusing to return anything though and leaves the textbox I display the workItemsToDisplay in empty. I'm not familiar with regular expressions and i'm sure this is where the issue stems from. Not sure if Microsoft already has sample code to construct a display of Work Items from the response.
Don't use a regex. That's JSON, use a JSON parsing library (JSON.Net is the de facto standard in the .NET world) and then you can easily retrieve specific fields.

Is it possible to create an email-attachment on a Silverlight email?

I need to be able to send an email from a silverlight client-side application.
I've got this working by implementing a webservice which is consumed by the application.
The problem is that now I need to be able to add an attachment to the emails that are being sent.
I have read various posts, tried a dozen times to figure it out by myself, but to no prevail.
So now I find myself wondering if this is even possible?
The main issue is that the collection of attachments needs to be serializable. So, going by this, ObservableCollection - of type(FileInfo) is not working, ObservableCollection - of type (object) is not working... I've tried using List - of type(Stream), which serializes, but then i do not know how to create the file on the webservice side, as the stream-object does not have a name (which is the first thing I tried to assign to the Attachment object which will then be added to the message.attachments)... I'm kind of stuck in a rut here.
Can anybody maybe shed some light on this please?
I figured out how to do this, and it wasn't really as difficult as it appeared.
Create the following in your webservice-namespace:
`
[Serializable]
public class MyAttachment
{
[DataMember]
public string Name { get; set; }
[DataMember]
public byte[] Bytes { get; set; }
}`
Then add the following to your web-method parameters:
MyAttachment[] attachment
Add the following in the execution blocks of your web-method:`
foreach (var item in attachment)
{
Stream attachmentStream = new MemoryStream(item.Bytes);
Attachment at = new Attachment(attachmentStream, item.Name);
msg.Attachments.Add(at);
}`
Create the following property (or something similar) at your client-side:
`
private ObservableCollection<ServiceProxy.MyAttachment> _attachmentCollection;
public ObservableCollection<ServiceProxy.MyAttachment> AttachmentCollection
{
get { return _attachmentCollection; }
set { _attachmentCollection = value; NotifyOfPropertyChange(() => AttachmentCollection); }
}`
New up the public property (AttachmentCollection) in the constructor.
Add the following where your OpenFileDialog is supposed to return files:`
if (openFileDialog.File != null)
{
foreach (FileInfo fi in openFileDialog.Files)
{
var tempItem = new ServiceProxy.MyAttachment();
tempItem.Name = fi.Name;
var source = fi.OpenRead();
byte[] byteArray = new byte[source.Length];
fi.OpenRead().Read(byteArray, 0, (int)source.Length);
tempItem.Bytes = byteArray;
source.Close();
AttachmentCollection.Add(tempItem);
}
}`
Then finally where you call your web-method to send the email, add the following (or something similar):
MailSvr.SendMailAsync(FromAddress, ToAddress, Subject, MessageBody, AttachmentCollection);
This works for me, the attachment is sent with the mail, with all of its data exactly like the original file.

How do I use RegEx to insert into a JSON response?

I'm using JSON for a web application I'm developing. But for various reasons I need to create "objects" that are already defined on the client script based on the JSON response of a service call. For this I would like to use a regex expression in order to insert the "new" statements into the JSON response.
function Customer(cust)
{
this.Name = null;
this.ReferencedBy = null;
this.Address = null;
if (cust != null)
{
this.Name = cust.Name;
this.ReferencedBy = cust.ReferencedBy;
this.Address = cust.Address;
}
}
The JSON response is returned by an ASP.NET AJAX Service and it contains a "__type" member that could be used to determine the object type and insert the "new" statement.
Sample JSON:
{"__type":"Customer", "ReferencedBy":{"__type":"Customer", "Name":"Rita"}, "Name":"Joseph", "Address":"123 {drive}"}
The resulting string would look like this:
new Customer({"ReferencedBy":new Customer({"Name":"Rita"}), "Name":Joseph", "Address":"123 {drive}"})
I got this so far but it doesn't work right with the ReferencedBy member.
match:
({"__type":"Customer",)(.*?})
replace:
new Customer({$2})
Hmmm why don't you try to make a simplier way to do it? e.g.:
var myJSON = {"__type":"Customer", "ReferencedBy":{"__type":"Customer", "Name":"Rita"}, "Name":"Joseph", "Address":"123 {drive}"};
after check the type: myJSON.__type, and if it is customer, then:
new Customer({"ReferencedBy":new Customer({"Name":myJSON.ReferencedBy.Name}), "Name":myJSON.Name, "Address":myJSON.Address });
It is because you already have a defined data structure, it is not neccessary to use regex to match pattern & extract data.