How to modify the field values of newly created Item/Page from sitecore Webservice - web-services

By using Sitecore webservice I created a new Page Item as Below.
var scClient = new VisualSitecoreServiceSoapClient();
// another code
var xmlNode = scClient.AddFromTemplate(parentId, pagetemplateId,itemName,database,credentials)
I cannot use the Database Items, just the web service.
From xmlNode I get the newly created GUID/Id. How do I edit the fields of newly created Item from the webservice only?

You can use Save() method like this:
string itemId = // id from AddFromTemplate() xmlNode
string fieldId = "{some-id-of-the-field}"; // id of the field
XDocument fieldXml = new XDocument(
new XElement("sitecore",
new XElement("field",
new XAttribute("itemid", itemId),
new XAttribute("language", "en"),
new XAttribute("version", 1),
new XAttribute("fieldid", fieldId),
new XElement("value", "new value of the field")
)
)
);
XElement fieldResponse = scClient.Save(fieldXml, "web", credentials);
EDIT:
In response to your comment: No, you cannot use field name instead of field id. Still you can use GetItemFields method exposed in VisualSitecoreServiceSoapClient to list all the fields of the item and then determine what is the id of the field with given name:
public XmlDocument GetItemFields(string id, string language, string version, bool allFields, string databaseName, Credentials credentials)

Related

Update specific attribute using UpdateItemEnhancedRequest DynamoDb java sdk2

We have a DynamoDB table which has an attribute counter, which will be decremented asynchronously by multiple lambda based on an event. I am trying to update the counter using UpdateItemEnhancedRequest (using the Dynamodb Enhanced Client. - JAVA SDK 2). I am able to build the condition for updating the counter but it updates the entire item and not just the counter. Can somebody please guide on how to update a single attribute using DynamoDb Enhanced Client?
Code Sample
public void update(String counter, T item) {
AttributeValue value = AttributeValue.builder().n(counter).build();
Map<String, AttributeValue> expressionValues = new HashMap<>();
expressionValues.put(":value", value);
Expression myExpression = Expression.builder()
.expression("nqctr = :value")
.expressionValues(expressionValues)
.build();
UpdateItemEnhancedRequest<T> updateItemEnhancedRequest =
UpdateItemEnhancedRequest.builder(collectionClassName)
.item(item)
.conditionExpression(myExpression)
.build();
getTable().updateItem(updateItemEnhancedRequest);
}
When you update a specific column, you need to specify which column to update. Assume we have this table:
Now assume we want to update the archive column. You need to specify the column in your code. Here we change the archive column of the item that corresponds to the key to Closed (a single column update). Notice we specify the column name by using the HashMap object named updatedValues.
// Archives an item based on the key
public String archiveItem(String id){
DynamoDbClient ddb = getClient();
HashMap<String,AttributeValue> itemKey = new HashMap<String,AttributeValue>();
itemKey.put("id", AttributeValue.builder()
.s(id)
.build());
HashMap<String, AttributeValueUpdate> updatedValues =
new HashMap<String,AttributeValueUpdate>();
// Update the column specified by name with updatedVal
updatedValues.put("archive", AttributeValueUpdate.builder()
.value(AttributeValue.builder()
.s("Closed").build())
.action(AttributeAction.PUT)
.build());
UpdateItemRequest request = UpdateItemRequest.builder()
.tableName("Work")
.key(itemKey)
.attributeUpdates(updatedValues)
.build();
try {
ddb.updateItem(request);
return"The item was successfully archived";
NOTE: This is not the Enhanced Client.
This code is from the AWS Tutorial that show how to build a Java web app by using Spring Boot. Full tutorial here:
Creating the DynamoDB web application item tracker
TO update a single column using the Enhanced Client, call the Table method. This returns a DynamoDbTable instance. Now you can call the updateItem method.
Here is the logic to update the the archive column using the Enhanced Client. Notice you get a Work object, call its setArchive then pass the Work object. workTable.updateItem(r->r.item(work));
Java code:
// Update the archive column by using the Enhanced Client.
public String archiveItemEC(String id) {
DynamoDbClient ddb = getClient();
try {
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(getClient())
.build();
DynamoDbTable<Work> workTable = enhancedClient.table("Work", TableSchema.fromBean(Work.class));
//Get the Key object.
Key key = Key.builder()
.partitionValue(id)
.build();
// Get the item by using the key.
Work work = workTable.getItem(r->r.key(key));
work.setArchive("Closed");
workTable.updateItem(r->r.item(work));
return"The item was successfully archived";
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
This answer shows both ways to update a single column in a DynamoDB table. The above tutorial now shows this way.
In your original solution, you're misinterpreting the meaning of the conditionExpression attribute. This is used to validate conditions that must be true on the item that matches the key in order to perform the update, not the expression to perform the update itself.
There is a way to perform this operation with the enhanced client without needing to fetch the object before making an update. The UpdateItemEnhancedRequest class has an ignoreNulls attribute that will exclude all null attributes from the update. This is false by default, which is what causes a full overwrite of the object.
Let's assume this is the structure of your item (without all the enhanced client annotations and boilerplate, you can add those):
class T {
public String partitionKey;
public Int counter;
public String someOtherAttribute
public T(String partitionKey) {
this.partitionKey = partitionKey;
this.counter = null;
this.someOtherAttribute = null
}
}
You can issue an update of just the counter, and only if the item exists, like this:
public void update(Int counter, String partitionKey) {
T updateItem = new T(partitionKey)
updateItem.counter = counter
Expression itemExistsExpression = Expression.builder()
.expression("attribute_exists(partitionKey)")
.build();
UpdateItemEnhancedRequest<T> updateItemEnhancedRequest =
UpdateItemEnhancedRequest.builder(collectionClassName)
.item(item)
.conditionExpression(itemExistsExpression)
.ignoreNulls(true)
.build();
getTable().updateItem(updateItemEnhancedRequest);
}

Signature disappears when inserting documents to template

I'm trying to insert a word document into a Docusign template. The document inserts properly, but in addition to the two signers set up in the code, one of the signers that was on the template stays. Also, the second signature field is removed. Is there a setting that I'm missing? Here's my code:
List<TemplateRole> roleslist = new List<TemplateRole>();
TemplateRole InternalSignerRole = new TemplateRole(); // Set the Template Roles for the Internal Signer
InternalSignerRole.Email = _currentDocInfo.sInternalSignerEmail;
InternalSignerRole.Name = _currentDocInfo.sInternalSignerName;
InternalSignerRole.RoleName = "SignerInternal";
roleslist.Add(InternalSignerRole); // add to Template Roles list
TemplateRole ExternalSignerRole = new TemplateRole(); // Set the Template Roles for the External Signer
ExternalSignerRole.Email = _currentDocInfo.sExternalSignerEmail; //Create Template Roles for ExternalSigner
ExternalSignerRole.Name = _currentDocInfo.sExternalSignerEmail;
ExternalSignerRole.RoleName = "SignerExternal";
roleslist.Add(ExternalSignerRole);
var apiClient = new ApiClient(conn.Base_URL);
DocuSign.eSign.Client.Configuration.Default.ApiClient = apiClient;
DocuSign.eSign.Client.Configuration.Default.AddDefaultHeader("X-DocuSign-Authentication", authHeader);
string accountId = null;
// login call is available in the authentication api
var authApi = new AuthenticationApi();
var loginInfo = authApi.Login();
// parse the first account ID that is returned (user might belong to multiple accounts)
accountId = loginInfo.LoginAccounts[0].AccountId;
var baseUrl = loginInfo.LoginAccounts[0].BaseUrl;
var separator = new string[] { "/restapi" };
var basePath = baseUrl.Split(separator, StringSplitOptions.None)[0] + "/restapi";
apiClient = new ApiClient(basePath);
EnvelopeDefinition envDef = new EnvelopeDefinition();
envDef.EmailSubject = emailSubject;
envDef.EmailBlurb = emailBody;
//add custom fields you sent over with the document
envDef.CustomFields = letterCustomFields;
// Add a document to the envelope
envDef.Documents = letterDocs;
// Add a recipient to sign the document
envDef.TemplateRoles = roleslist;
envDef.TemplateId = "478d85c2-dc7c-4a89-a985-7d7a9101e36a";
First off, please don't use legacy authentication. That is old, not as secure and should not be used in new code that you're building.
Note that tabs (signature elements) are associated with both a recipient (a specific one) as well as a document (a specific one).
If you are trying to replace a document in a template, when creating an envelope from it (which is what you're doing, you're not replacing the document in the template, but rather in the envelope you create), you need to ensure the tabs refer to the same document and same recipient (based on the role).
Also, another recommendation is to use composite templates, which provide more flexibility for such scenarios. See excellent blog post by Gil Vincent for more information.

Not able to pre populate the custom field using c# code in HelloSign

I was trying to pre-populate the custom field value from C# code but I was not able to. I have used following snippet of code to do so
var client = new Client("MY API KEY");
var request = new TemplateSignatureRequest();
request.AddTemplate("docID");
request.Title = "Test Titel";
request.Subject = "Test Subject";
request.Message = "Test Message.";
request.AddSigner("Me", "xxxxx#example.com", "Test");
request.AddSigner("Client", "xxxxx#example.com", "Test");
var firstName = request.GetCustomField("FirstName");
firstName.Value = "John";
request.TestMode = true;
var response = client.SendSignatureRequest(request);
I have already assigned the customer field to me and verified the API ID key for the field also.But still not able to get the result. Is there anything else we need to add to so that value John will be shown.
Try
request.AddCustomField("fName", "Alex");
Also, please feel free to reach out to apisupport#hellosign.com for more assistance if you would like.

How to search for Items that doesn't contain certain keywords using Sitecore Advanced Database Crawler?

I have millions of items in the database. And user can search those items based on the keyword. In the search function, I need to provide a feature that search for NOT that keyword.
For example Item A has a field called msg and the value is Sitecore is awesome and great.
In the search box, user can check the checkbox that indicates to show any item that doesn't contain the keyword. Maybe user key in is keyword, so Item A will not be displayed or retrieved by ADC.
Edit: Currently I'm using sitecore6.6, thus Search method has been deprecated. I have tried the Not keyword by using Occurrence.MustNot, but it doesn't return any result.
The Sitecore Advanced Database Crawler is an extension of the Sitecore.Search API and Sitecore.Search API is a wrapper around Lucene.
In Lucene you can user queries with NOT or - to exclude something like "Sitecore NOT awesome" or "Sitecore -awesome".
To exclude something you need at least one include term.
Not sure if it works, but give it a try.
This is untested, but you might have luck by using a MatchAllDocsQuery and supplying the keywords in the form of a Filter.
BooleanQuery booleanQuery = new BooleanQuery();
QueryParser queryParser = new QueryParser("msg", new StandardAnalyzer());
Query userQuery = queryParser.Parse("Sitecore is awesome and great");
booleanQuery.Add(userQuery, reverseQuery.Checked ? BooleanClause.Occur.MUST_NOT : BooleanClause.Occur.MUST);
MatchAllDocsQuery matchAllQuery = new MatchAllDocsQuery();
Filter filter = new QueryFilter(booleanQuery);
using (QueryRunner queryRunner = new QueryRunner("myIndex"))
{
var skinnyItems = queryRunner.RunQuery(matchAllQuery, filter, ...)
}
What I have done to NOT include the keywords associated with the result item set is this:
protected List<Item> getSearchResults(string queryToSearch, string selectedFilter, string notToSearch)
{
Database db = Sitecore.Context.Database;
var index = SearchManager.GetIndex("siteSearchIndexName");
using (SortableIndexSearchContext context = new SortableIndexSearchContext(index))
{
if (!String.IsNullOrWhiteSpace(query))
{
query.ToLower();
CombinedQuery cq = new CombinedQuery();
QueryBase qbKeyword = new FieldQuery("_orderkeywordpair", query);
QueryBase qbContent = new FieldQuery("_content", query);
QueryBase qbHtml = new FieldQuery("html", query);
if (!String.IsNullOrWhiteSpace(selectedFilter) && selectedFilter.ToLower() != "all")
{
QueryBase qbFilter = new FieldQuery("_pagetype", selectedFilter);
cq.Add(qbFilter, QueryOccurance.Must);
}
cq.Add(qbKeyword, QueryOccurance.Should);
cq.Add(qbContent, QueryOccurance.Must);
cq.Add(qbHtml, QueryOccurance.MustNot);
SearchHits hits = context.Search(cq);

How to get all list items regardless of view using Lists webservice

I have a list with only one view exposed on it (default view). That only view has a filter with a field Assigned To = [Me] so all users logged in can only see their own list items. This list items get copied from a master list.
I have this code to get the list items from the list with only one view but it only returns the items assigned to myself (as expected). Is there anyway to get all list items in a list regardless of the view?
var xmlDoc = new XmlDocument();
XmlNode query = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");
XmlNode viewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");
XmlNode queryOptions = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", "");
queryOptions.InnerXml = "<MeetingInstanceID>-1</MeetingInstanceID><ViewAttributes Scope='RecursiveAll' />";
return destLists.GetListItems(listConfig.DestGuid,
listConfig.DestViewGuid,
query,
viewFields,
RowLimit,
queryOptions,
null);
Answered here # http://www.sharepoint.stackexchange.com/questions/10118/how-to-get-all-list-items-regardless-of-view-using-lists-webservice