Repeated execution of code activity in SharePoint workflow? - sharepoint

I have a custom workflow implementation what requires updation of an external DB. I created a simple workflow for text purpose and found a strange thing!
my Db update/insert code is placed in a code activity of the workflow. it seems the code activity is executed multiple times when the workflow is invoked on a simple list item in sharepoint custom list. Here is my workflow:
and my code is:
private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
workflowProperties.Item["Title"] = "Processed by workflow at "+ DateTime.Now;
workflowProperties.Item.Update();
}
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
Random rnd = new Random();
string conStr = "Data Source=192.168.1.57\\TRIBIRD;Initial Catalog=XXXXXX;User ID=XXXXXX;Password=XXXXXXXXXX";
SqlConnection connection = new SqlConnection(conStr);
SqlCommand command = connection.CreateCommand();
command.CommandType = System.Data.CommandType.Text;
command.CommandText = "INSERT INTO XXXX VALUES(" + rnd.Next() + ",'THE CONTENT FROM SHAREPOINT WORKFLOW','EN',1,1,'BRT')";
connection.Open();
command.ExecuteNonQuery();
command.Dispose();
connection.Close();
}
in the DB i get more than 1 row for the workflow execution! interesting thing is, during each execution, the number of rows added varies.
Why is this happening? what is my mistake?
Any ideas and suggestions are welcome.

Make sure you are running the latest patches and updates for SharePoint.
Earlier versions in 2007 would allow cyclic self-triggers (e.g. re-triggering). Later versions do not (but still allow co-cyclic triggers). I suspect this is the problem and a "cascade" is starting by Update method. Just a hunch.
This should be fixed in SP2: Service Pack 2 prevents an on-change workflow from starting itself

Related

Selenium Script to create multiple records for Dynamics CRM 365 Account Entity

I have developed a Selenium script for Creating Multiple Records in Dynamics CRM 365 using Excel Sheet for Account entity but when i run the script the CRM System Automatically creates a blank record initially. Please find below screenshot and code for the same. (noofaccountstocreate is a variable which is used to store the integer value)
int q;
for (q = 0; q <= noofaccountstocreate; q++)
{
chrome.FindElement(By.Id("account|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.account.NewRecord")).Click();
Thread.Sleep(2000);
chrome.SwitchTo().Frame(chrome.FindElement(By.Id("contentIFrame1")));
//Thread.Sleep(3000);
Actions ikl_act3 = new Actions(chrome);
ikl_act3.MoveToElement(chrome.FindElement(By.Id("name_d"))).SendKeys("Test " + q);
//ikl_act3.Click();
Thread.Sleep(2000);
ikl_act3.Perform();
Thread.Sleep(2000);
ikl_act3.Release();
Thread.Sleep(2000);
chrome.FindElement(By.XPath("//*[#id='savefooter_statuscontrol']")).Click();
Thread.Sleep(10000);
chrome.SwitchTo().DefaultContent();
Thread.Sleep(2000);
chrome.FindElement(By.Id("Tabnav_accts-main")).Click();
Thread.Sleep(2000);}
Please see image here (Selenium Multiple Addition Error)
Microsoft have a Selenium adapter for Dynamics 365 here on GitHub. Try creating your account records through its API instead. Your code would look something like:
using (var xrmBrowser = new XrmBrowser(TestSettings.Options))
{
xrmBrowser.LoginPage.Login(_xrmUri, _username, _password);
xrmBrowser.GuidedHelp.CloseGuidedHelp();
xrmBrowser.ThinkTime(500);
xrmBrowser.Navigation.OpenSubArea("Sales", "Accounts");
xrmBrowser.ThinkTime(2000);
xrmBrowser.Grid.SwitchView("Active Accounts");
xrmBrowser.ThinkTime(1000);
xrmBrowser.CommandBar.ClickCommand("New");
xrmBrowser.ThinkTime(4000);
xrmBrowser.Entity.SetValue("name", "Test API Account");
xrmBrowser.Entity.SetValue("telephone1", "555-555-5555");
xrmBrowser.Entity.SetValue("websiteurl", "https://easyrepro.crm.dynamics.com");
xrmBrowser.CommandBar.ClickCommand("Save & Close");
xrmBrowser.ThinkTime(2000);
}
It's hard to diagnose your issue without debugging.

workflow replicator activity: how to determine if task was approved or rejected

I have basic workflow with replicator activity inside it. Replicator contains my custom sequence activity with standard create task --> ontaskchanged --> complete task sequence.
Now: tasks are created and can be completed without problem. The thing is I cannot find a way to get a value of completed task. Was it approved or rejected ?
Please provide couple lines of code of replicator's ChildCompleted event to get anything out of Sequence activity instance (or any other way).
thanks
UPDATE: It seems in order to exchange values between instances of workflow you need to use DependencyProperty. So solution here is:
1) add DependencyProperty to parent workflow and add property which you will use to store value like this:
public static DependencyProperty childStatusProperty =
System.Workflow.ComponentModel.DependencyProperty.Register("childStatus",
typeof(string), typeof(parentWorkflowTypeName));
public string childStatus
{
get
{
return (string)base.GetValue(childStatusProperty);
}
set
{
base.SetValue(childStatusProperty, value);
}
}
2) in custom sequence activity access parent's instance and use defined DependencyProperty to set property to value like this:
private void completeTask1_MethodInvoking(object sender, EventArgs e)
{
var replicator = this.Parent;
var workflowParent = (parentWorkflowTypeName)replicator.Parent;
workflowParent.childStatus = "my custom status value";
}
3) read this value using normal property:
//from parent workflow
string status = childStatus;
The issue is that you have to record somewhere the list of all tasks created. I guess you are creating the tasks in parallel (not sequential).
I had the same issue, it took me a while to fix this.
Please check this link as a good starting point: http://rmanimaran.wordpress.com/2010/12/02/sharepoint-workflow-replicator-parallel-approval-problem-solution/

My C# window application cannot insert new record to sql database both in ADO.net and Entity Framework

Good day people! I have a problem with my C# window application.
I can't insert new record to database. I have sought for many tutorial in ADO.net and Entity Framework.
I have been tackling it in Entity Framework because that is my preference.
My piece of Entity Framework code would run successfully to insert new record.
When i go back-end to see the result; none is found.I am using Visual studio 2010.
And i developed the database through visual studio (the normal way of adding new item).
I have this piece of code:
public bool CreateStaff(string txtUserName, string gender, string txtProfession, string txtMobilePhone, string txtAddress)
{
//using (MyHospDataEntities db = new MyHospDataEntities())
//{
try
{
StaffData addstaff = new StaffData();
addstaff.StaffName = txtUserName;
addstaff.Sex = gender;
addstaff.DateCreated = DateTime.Now;
addstaff.Profession = txtProfession;
addstaff.PhoneNumber = txtMobilePhone;
addstaff.Address = txtAddress;
mms.StaffDatas.AddObject(addstaff);
mms.SaveChanges();
}
catch (Exception exp)
{
throw new Exception("ERROR: Unable to Add Staff - " + exp.Message.ToString(), exp);
}
//}
return true;
}
"mms" this is DbContext?
You can try this
mms.StaffDatas.Add(new StaffDatas {});
mms.SaveChanges();
Make sure your connection string is correct. Some times the connection string like this
"Data Source=.\SQLEXPRESS;AttachDbFilename="+Application.StartupPath +"Database1.mdf;Integrated Security=True;User Instance=True"
give you the same problem if you have .exe and database file are same in runtime and in bin/debug folder.

SPQuery and RowLimit

I have around 10000+ rows(Listitems) in a list I want to query.
I want to iterate each of the item in a timerJob - but I cant take all of them at a time
since : Object Model Override - NO, ListView threshold - 1000 - in the FARM level and i we cant change this.
What is the way for me to iterate all the 10000+ (like a batch) ??
You should use a ContentIterator. This will allow you to iterate over the contents of very large lists without triggering an SPQueryThrottledException.
For example:
SPList list = SPContext.Current.Web.Lists["MyList"];
// Build query using an iterator-defined WHERE clause
string query = string.Format("<Where><Eq><FieldRef Name='MyFieldName'/><Value Type='Text'>MyFieldValue</Value></Eq></Where>{0}", ContentIterator.ItemEnumerationOrderByNVPField);
// Instantiate iterator and use it to process the list
ContentIterator iterator = new ContentIterator();
iterator.ProcessListItems(list, query, ProcessListItem, ProcessListItemError);
Then you'd define your ProcessListItem and ProcessListItemError thusly:
static void ProcessListItem(SPListItem item) {
Console.WriteLine("ProcessListItem: Name {0}", item.Title);
}
static bool ProcessListItemError(SPListItem item, Exception e) {
Console.WriteLine("ERROR: message {0}", e.Message);
return true;
}
I'd also recommend you review Microsoft's Best Practices with SharePoint Server articles, in particular "Writing Efficient Code In SharePoint Server", which further discusses properly writing queries.

Cannot update document property on ItemAdded event when using Vista

We are trying to create a custom event handler that would fire on ItemAdded event. The event handler then updates the document with a unique ID value to a column in this document library.
Our solution works fine, except when a user on Vista is trying to save a new document from Office 2007. In this scenario the document is stored to document library but Unique ID column is empty, and there is no exception.
Vista Users can upload document(s) to library without a problem. Everything else works fine on XP and Win2k3 operating systems.
Has anyone seen something similar, and what might be the problem here? To demonstrate the problem we are using DateTime.Now as unique ID.
using Microsoft.SharePoint;
public class TestReciever : SPItemEventReceiver
{
public override void ItemAdded(Microsoft.SharePoint.SPItemEventProperties properties)
{
try {
DisableEventFiring();
properties.ListItem("UniqueID Column") = DateTime.Now.ToString();
properties.ListItem.SystemUpdate();
EnableEventFiring();
}
catch (Exception ex) {
// handle exception
}
}
}
We have noticed exactly the same thing happening. When the 2007 doc is added to the library, the properties from the list are added to it (blank).
Then the (synchronous) event handler is called, updating the list with the correct values for the UniqueID column.
Then the inbuilt property mapping to 2007 docs kicks in and overwrites your values with those stored in the 2007 doc (not raising an item updated event again).
This means that the list now has a blank for your column.
If you change to an asynchronous event you may see what we did and that the slight delay for asynchronous meant that the property mapping to 2007 docs happened first (we think) meaning the value was stored correctly.
It is possible to break the property mapping between the list and office, but that is only a workaround.
I cannot for the life of me find where this info is on an MS site, but it is a known problem. Perhaps you can hang in there for SP2 (may even be fixed in SP1, but am unsure).
At the end we contacted Microsoft and they provided us with the following workaround solution. The key here is to delay item update in a separate thread.
private Guid listID;
private Guid itemID;
private Guid siteID;
public override void ItemAdded(Microsoft.SharePoint.SPItemEventProperties properties)
{
DisableEventFiring();
item = properties.ListItem;
listID = properties.ListId;
itemID = properties.ListItem.UniqueId;
siteID = properties.SiteId;
Threading.Thread setDocumentInternalIDThread = new Threading.Thread(SetInternalID);
setDocumentInternalIDThread.Start();
EnableEventFiring();
}
private void SetInternalID()
{
try {
Threading.Thread.Sleep(10000);
using (SPSite site = new SPSite(siteID)) {
using (SPWeb web = site.OpenWeb()) {
SPList list = web.Lists(listID);
SPListItem item = list.Items(itemID);
item(Common.CustomID) = Common.GetAlphaPrefix() + Common.GetDocNumber();
item.SystemUpdate();
}
}
}
catch (Exception ex) {
Log(ex.Message);
}
}
Another workaround is to set the custom field that is being updated in the event receiver to be read only (set the fields ReadOnly property to TRUE). This has a few pros and cons. This is ideal for a unique id solution, because there is no way for the user to modify the value. However, the field is hidden to the UI, so managing it becomes more troublesome, and the field can't be used in labels, or quick parts. You can set the ShowInDisplayForm property of the field to TRUE to have the field display in the view form, but not the edit form. The field can also be added to your views. This is the best workaround I have found for this issue to date.
This is an issue with Office 2007 and the WSS 3.0 xml parser. When the properties are promoted from the Office 2007 document, the parser attempts to assign document properties to the list properties in SharePoint (property promotion). The problem is that this event occurs after any ItemAdded, or ItemUpdated events, so the property gets overwritten with the value in the document, which is of course, blank. Microsoft has raised this as a bug, and I was hoping for a fix in SP2, but no such luck.

Resources