Error when trying to setTitle on new DB - xpages

I'm working on an Archiving Application with this code in it:
var arcName:String = "Archives/" + aDBName + "-Backup-" + toDay + "-" + thisTime.slice(0,5);
var server:String = appDB.getServer();
var arcDB:NotesDatabase = appDB.createCopy(server, arcName);
arcDB.setTitle("This is a Test");
but it fails at the arcDB.setTitle - the new copy of the Database is created so there is no issue to that point.
This is from the IBM Knowledge base:
var db2:NotesDatabase = db.createCopy(null, "names2");
db2.setTitle("Copy of names");
I can't see the difference between these two pieces of code.
Am I missing something?

Usually when something doesn't work with XPages that relates to database or design objects the first thing I check is the Maximum Internet Name and password Access https://stackoverflow.com/a/23045860/1187943
Or change so I do the work using sessionAsSigner or sessionAsSignerWithFullAccess

If you don't care about the effectiveUser's access to the source database, their permissions to make a copy, and their access rights to create a NotesDatabase on the target Domino server, I'd absolutely second Fredrik's suggestion to use sessionAsSigner/WithFullAccess.
Additionally, I find it's best practice to use try/catches (helps with troubleshooting and errorHandling), object testing (.isOpen() when accessing a NotesDatabase), and returning an Object that can be read by the calling function.
Here's some example code that might help:
var copyNotesDatabase = function(dbName) {
var isSuccessful = true;
var responseMessage = "";
try {
//set appDB using dbName from function arguments
var appDB = session.getDatabase(session.getServerName(),dbName);
//var appDB = sessionAsSigner.getDatabase(session.getServerName(),"sourceDb.nsf");
//var appDB = sessionAsSignerWithFullAccess.getDatabase(session.getServerName(),"sourceDb.nsf");
if(appDB.isOpen()) {
var arcName:String = "Archives/" + aDBName + "-Backup-" + toDay + "-" + thisTime.slice(0,5);
var server:String = appDB.getServer();
//arcDB will be created based on appDB permissions, ie effectiveUser, or sessionAsSigner, etc.
var arcDB:NotesDatabase = appDB.createCopy(server, arcName);
if(arcDB.isOpen()) {
arcDB.setTitle("This is a Test");
responseMessage = "Successfully copied NotesDatabase!"
} else {
isSuccessful = false;
responseMessage = "Unable to open copied NotesDatabase.";
}
} else {
isSuccessful = false;
responseMessage = "Unable to open source NotesDatabase.";
}
} catch(e) {
print("Error from SSJS: " + e);
isSuccessful = false;
responseMessage = e;
}
return { status : isSuccessful, message : responseMessage };
}
With this function, you could do something like this:
function makeCopy(appName) {
var fObj = copyNotesDatabase(appName);
if(fObj.status) {
return "Successfully copied " + appName;
} else {
return fObj.message;
}
}
... at the very least, using a try/catch and returning your error will at least tell you why your current code isn't working. Hope this helps!

Related

Program terminates when calling WorkItemTrackingHttpClient.QueryByWiqlAsyc()

I am working on a program that gets a list of workitems in the committed state from Azure DevOps for a specific area path and iteration path. My code is based on an example found at the following link: https://learn.microsoft.com/en-us/azure/devops/integrate/quickstarts/work-item-quickstart?view=azure-devops
The issue I am running into is when QueryByWiqlAsync() is called, the program terminates and there are no errors for why it terminated. Below is the code in question. I tried calling QueryByWiqlAsync() with and without the ConfigureAwait(false) and that did not seem to make a difference. Any suggestions on what to try or what to fix are appreciated.
static async void GetWorkItemsToTaskFromADO(string tfs_project, string accessToken)
{
var credentials = new VssBasicCredential(string.Empty, accessToken);
var wiql = new Wiql()
{
Query = #"Select [Id] From WorkItems WHERE [System.TeamProject] = 'SampleADOProject' AND [System.AreaPath] = 'Sample\ADO\AreaPath' AND [System.IterationPath] = 'Sample\ADO\IterationPath' AND [System.State] = 'Committed'"
};
using (var httpClient = new WorkItemTrackingHttpClient(new Uri(tfs_project), credentials))
{
try
{
var result = await httpClient.QueryByWiqlAsync(wiql).ConfigureAwait(false);
var ids = result.WorkItems.Select(item => item.Id).ToArray();
var fields = new[] { "System.Id", "System.Title", "System.State" };
var workItems = await httpClient.GetWorkItemsAsync(ids, fields, result.AsOf).ConfigureAwait(false);
// output results to test what came back...
foreach (var workItem in workItems)
{
Console.WriteLine(
"{0}\t{1}\t{2}",
workItem.Id,
workItem.Fields["System.Title"],
workItem.Fields["System.State"]
);
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
Console.Read();
}
}
}

NetSuite SuiteScript 2.0 disable field based on checkbox

I apologize if this is a dumb question, but I am new to NetSuite, and have noticed that their documentation is absolutely ridiculously horrifyingly and atrociously disgusting. All humor and bitterness aside though, I can't find the details that should exists in SuiteAnswers. I can find the type Field or Record, but it doesn't show me the options available for those types. It just shows what methods to call to return a field or record.
So I have it on the fieldChanged event as the training specifies, and below is what I have.
function fieldChanged(context) {
debugger;
var customer = context.currentRecord
if (context.fieldId == 'custentity_apply_coupon') {
var field = record.getField("custentity_apply_coupon");
if (record.getValue("custentity_apply_coupon") == true) {
reord.getField("custentity_coupon_code").isDisabled = false;
}
else{
reord.getField("custentity_coupon_code").isDisabled = true;
}
field.isDisabled = false;
}
}
Turns out that, and I never found this in the documentation, that once you get the field from currentRecord.currentRecord, you can set it to disabled via field.isDisabled. Took me forever to find out that isDisabled was a property of field, and then took a complete guess to see that isDisabled was a get/set call for ClientSide Scripts. Below is the code that ended up working.
function fieldChanged(scriptContext) {
var customer = scriptContext.currentRecord;
if(scriptContext.fieldId == "custentity_sdr_apply_coupon"){
debugger;
var field = customer.getField("custentity_sdr_coupon_code");
field.isDisabled = !customer.getValue(scriptContext.fieldId);
if(field.isDisabled){
customer.setValue(field.id, "");
}
}
}
I hope this will help.
function fieldChanged(context) {
var currentRecord = context.currentRecord;
var approvalChkBox = currentRecord.getValue({
fieldId: 'supervisorapproval'
});
var memoField = currentRecord.getField("memo");
if (approvalChkBox)
memoField.isDisabled = true;
else
memoField.isDisabled = false;
}
Thats a good question, this is the simplest solution you are looking for. use getValue method and isDisabled to meet this requirement. the code is self explanatory. Good Luck.
function fieldChanged(context) {
var record = context.currentRecord;
var fieldname = context.fieldId;
var changedValue = record.getValue(fieldname); //getValue method is the key here
var couponid = record.getField('custentity_kld_coupon_code');
if (fieldname == 'custentity_kld_apply_coupon' && changedValue == true) {
couponid.isDisabled = false; //isDisabled helps you to enable or disable a field
} else {
couponid.isDisabled = true;
}
}
Totally agree. I think the SuiteScript 2.0 Student Guide could've been more helpful if they included a preview of their codes along the way.
For anyone else who is still following along, this code below worked for me. Thanks for everyone else that contributed in this post. Used your codes to create this too. I also included some other codes from the previous exercises (i.e. displaying a message when entering 'x' into the coupon code).
/**
* #NScriptType ClientScript
* #NApiVersion 2.0
*/
define([],
function() {
function fieldChanged (context) {
var customer = context.currentRecord;
if(context.fieldId = 'custentity_sdr_apply_coupon') {
var check = customer.getValue('custentity_sdr_apply_coupon');
var code = customer.getField('custentity_sdr_coupon_code');
if (check == true){
code.isDisabled = false;
} else {
code.isDisabled = true;
}
}
}
function saveRecord(context) {
var customer = context.currentRecord;
var empCode = customer.getValue('custentity_sdr_coupon_code')
if(empCode == 'x') {
alert('Invalid code value. Please try again');
return false;
}
return true;
}
return {
fieldChanged: fieldChanged,
saveRecord: saveRecord,
};
});
var objRec_Curr = scriptContext.currentRecord;
var TransferType = objRec_Curr.getCurrentSublistValue({sublistId:'xxxxxxxxxx', fieldId : 'xxxxxxxxxxxx'});
if(TransferType == 'ABC')
eval("nlapiDisableLineItemField('custpage_sublist_out', 'custpage_out_transfer_location', true)");
else
eval("nlapiDisableLineItemField('custpage_sublist_out', 'custpage_out_transfer_location', false)");

What is the PostFileWithRequest equivalent in ServiceStack's 'New API'?

I want to post some request values alongside the multipart-formdata file contents. In the old API you could use PostFileWithRequest:
[Test]
public void Can_POST_upload_file_using_ServiceClient_with_request()
{
IServiceClient client = new JsonServiceClient(ListeningOn);
var uploadFile = new FileInfo("~/TestExistingDir/upload.html".MapProjectPath());
var request = new FileUpload{CustomerId = 123, CustomerName = "Foo"};
var response = client.PostFileWithRequest<FileUploadResponse>(ListeningOn + "/fileuploads", uploadFile, request);
var expectedContents = new StreamReader(uploadFile.OpenRead()).ReadToEnd();
Assert.That(response.FileName, Is.EqualTo(uploadFile.Name));
Assert.That(response.ContentLength, Is.EqualTo(uploadFile.Length));
Assert.That(response.Contents, Is.EqualTo(expectedContents));
Assert.That(response.CustomerName, Is.EqualTo("Foo"));
Assert.That(response.CustomerId, Is.EqualTo(123));
}
I can't find any such method in the new API, nor any overrides on client.Post() which suggest that this is still possible. Does anyone know if this is a feature that was dropped?
Update
As #Mythz points out, the feature wasn't dropped. I had made the mistake of not casting the client:
private IRestClient CreateRestClient()
{
return new JsonServiceClient(WebServiceHostUrl);
}
[Test]
public void Can_WebRequest_POST_upload_binary_file_to_save_new_file()
{
var restClient = (JsonServiceClient)CreateRestClient(); // this cast was missing
var fileToUpload = new FileInfo(#"D:/test/test.avi");
var beforeHash = this.Hash(fileToUpload);
var response = restClient.PostFileWithRequest<FilesResponse>("files/UploadedFiles/", fileToUpload, new TestRequest() { Echo = "Test"});
var uploadedFile = new FileInfo(FilesRootDir + "UploadedFiles/test.avi");
var afterHash = this.Hash(uploadedFile);
Assert.That(beforeHas, Is.EqualTo(afterHash));
}
private string Hash(FileInfo file)
{
using (var md5 = MD5.Create())
{
using (var stream = file.OpenRead())
{
var bytes = md5.ComputeHash(stream);
return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();
}
}
}
None of the old API was removed from the C# Service Clients, only new API's were added.
The way you process an uploaded file inside a service also hasn't changed.

How to save base64 file to the client using JavaScript?

I have the gotten a certain result from the Notes tab.
The link you see inside the iframe is the name of the file.
I have the DocumentBody from the annotation in some format that looks like base64.
How do I download it?
Thanks,
Fabio
Perform a JQuery request to a URL like this
Xrm.Page.context.getServerUrl() + "XRMServices/2011/OrganizationData.svc/ActivityMimeAttachmentSet(guid'abc...')?$select=Body"
By specifying the select you will request only what you want.
Assign the result to a variable and prepend
data:application/pdf;base64,
From there you could display it inline as an HTML object or try to open it as a new window with
window.location or window.open or document.location.href
I had already the base64 documentbody string extracted like this:
function getSla() {
// Define SOAP message
var objectId;
if (typeof crmForm === "undefined") {
objectId = parent.crmForm.ObjectId;
}
else {
objectId = crmForm.ObjectId;
}
var xml =
[
"<?xml version='1.0' encoding='utf-8'?>",
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" ",
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ",
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">",
GenerateAuthenticationHeader(),
"<soap:Body>",
"<RetrieveMultiple xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>",
"<query xmlns:q1='http://schemas.microsoft.com/crm/2006/Query' ",
"xsi:type='q1:QueryExpression'>",
"<q1:EntityName>annotation</q1:EntityName>",
"<q1:ColumnSet xsi:type='q1:AllColumns' />",
"<q1:Distinct>false</q1:Distinct><q1:Criteria><q1:FilterOperator>And</q1:FilterOperator>",
"<q1:Conditions><q1:Condition><q1:AttributeName>objectid</q1:AttributeName><q1:Operator>Equal</q1:Operator>",
"<q1:Values><q1:Value xsi:type=\"xsd:string\">",
objectId,
"</q1:Value></q1:Values></q1:Condition></q1:Conditions></q1:Criteria>",
"</query>",
"</RetrieveMultiple>",
"</soap:Body>",
"</soap:Envelope>"
].join("");
var resultXml = executeSoapRequest("RetrieveMultiple", xml);
var result = filter(resultXml.getElementsByTagName("q1:filename"), function (element) {
return /master.*sla/i.test(element.text);
});
if (result.length == 0) {
return null;
}
else {
return result[0].parentNode;
}
}
function getSlaDocumentBody(sla) {
return sla.getElementsByTagName("q1:documentbody")[0].text;
}
window.open("data:application/pdf;base64," + getSlaDocumentBody(sla));
It opened a new window with the string data:application/pdf.......... in the address bar but did nothing. I would prefer that solution indeed.
Ended up using srasmussen solution in here: http://social.microsoft.com/Forums/en/crm/thread/05134277-dd76-4fbb-8f6e-89b1a2a45af1.
var URL = serverUrl + "/userdefined/edit.aspx?etc=5&id=" + slaId;
$.get(URL, function (data) {
var WRPCTokenElement = $(data).find("[WRPCTokenUrl]");
if (WRPCTokenElement) {
var WRPCTokenUrl = WRPCTokenElement.attr("WRPCTokenUrl");
if (WRPCTokenUrl) {
URL = "/Activities/Attachment/download.aspx?AttachmentType=5&AttachmentId=" + slaId + "&IsNotesTabAttachment=undefined" + WRPCTokenUrl;
window.open(URL);
}
}
return false;
});

Check if MOSS resource exists generating unexpected 401's

I have a webdav function listed below:
The behavior is completely unexpected....
When I first run the function and pass a URL to a resource (folder in sharepoint) that does not exist, I get a 404 which is expected. I then use another function to create the resource using THE SAME credentials as in this method. No problems yet...
However on 2nd run, after the resource has been created - when I check if resource exists, now I get a 401.
Whats important to note here is that the same credentials are used to check for 401 and create folder, so clearly the credentials are fine...
So it must be something else.... All I want to do is check if a resource exists in SharePoint.... any ideas how to improve this function? Or any theory as to why its giving this 401...
private bool MossResourceExists(string url)
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "HEAD";
// Create a new CredentialCache object and fill it with the network
// credentials required to access the server.
var myCredentialCache = new CredentialCache();
if (!string.IsNullOrEmpty(this.Domain ))
{
myCredentialCache.Add(new Uri(url),
"NTLM",
new NetworkCredential(this.Username , this.Password , this.Domain )
);
}
else
{
myCredentialCache.Add(new Uri(url),
"NTLM",
new NetworkCredential(this.Username , this.Password )
);
}
request.Credentials = myCredentialCache;
try
{
request.GetResponse();
return true;
}
catch (WebException ex)
{
var errorResponse = ex.Response as HttpWebResponse;
if (errorResponse != null)
if (errorResponse.StatusCode == HttpStatusCode.NotFound)
{
return false;
}
else
{
throw new Exception("Error checking if URL exists:" + url + ";Status Code:" + errorResponse.StatusCode + ";Error Message:" + ex.Message ) ;
}
}
return true;
}
The only clue I have is that when using http://mysite.com/mydoclib/mytoplevelfolder it works.... any sub folders automatically give 401's....
The thing is that you can't pass the whole url that includes folders to the CredentialCache.Add() method.
For example:
http://MyHost/DocumentLibrary/folder1/folder2 will not work as an Uri to the Add() method, but
http://MyHost/DocumentLibrary/ will work.
I would guess that the lack of permissioning capabilities on folder level in SharePoint is the reason for this. Or the way that otherwise SharePoint handles folders.
What you can do is to separate the parameters in your method to accept a base url (including document libraries / lists) and a folder name parameter.
The CredentialCache gets the base url and the request object gets the full url.
Another way is to use the
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
credentials instead. And, if necessary, do an impersonation if you want to use another account than the executing one.
A third variation is to try with authentication type set to Kerberos instead of NTLM.
Here is my test code. I am able to reproduce the problem if I replace the problem with your code, and this code works for me.
static void Main(string[] args)
{
bool result = MossResourceExists("http://intranet/subtest/content_documents/", "testfolder/testfolder2");
}
private static bool MossResourceExists(string baseUrl, string folder)
{
string completeUrl = baseUrl + folder;
var request = (HttpWebRequest)WebRequest.Create(completeUrl);
request.Method = "HEAD";
// Create a new CredentialCache object and fill it with the network
// credentials required to access the server.
var myCredentialCache = new CredentialCache();
if (!string.IsNullOrEmpty(Domain))
{
myCredentialCache.Add(new Uri(baseUrl),
"NTLM",
new NetworkCredential(Username, Password, Domain)
);
}
else
{
myCredentialCache.Add(new Uri(baseUrl),
"NTLM",
new NetworkCredential(Username, Password)
);
}
request.Credentials = myCredentialCache;
//request.Credentials = System.Net.CredentialCache.DefaultCredentials;
try
{
WebResponse response = request.GetResponse();
return true;
}
catch (WebException ex)
{
var errorResponse = ex.Response as HttpWebResponse;
if (errorResponse != null)
if (errorResponse.StatusCode == HttpStatusCode.NotFound)
{
return false;
}
else
{
throw new Exception("Error checking if URL exists:" + completeUrl + ";Status Code:" + errorResponse.StatusCode + ";Error Message:" + ex.Message);
}
}
return true;
}
Hope this helps.

Resources