How do I trigger a Sharepoint Workflow from code? - sharepoint

I have a workflow that is triggered by the creation of a list item and sends out an email when the list item is created.
If I create a new item in that list through the Sharepoint front end it sends the email.
I have a small console application designed to set the list item through the Sharepoint API. This is run as a scheduled task on a daily basis ( the purpose of the list is to nominate someone for a daily rota ) in the middle of the night. The scheduled task is run with the credentials of the Site Collection Administrator for the site.
The list item is added but the workflow is not triggered. In the log I get the following message:
Declarative workflows cannot automatically start if the triggering action was performed by System Account. Canceling workflow auto-start.
It appears as though the list item is being added by the system account rather than the user who is running the code. What do I need to do in order to have my code interact with Sharepoint using the same identity that is running the application?

Consider explicitly impersonating one of your SharePoint users (in this case the site collection administrator.) I answered a similar question over here: UpdateListItem method and System Account
Once you've created a SPSite object using the context of the impersonated user all operations against that object and its children will be performed as that user.

It might be better to set your second workflow to being manually started, and then start it programmatically (which your System Account -can- do):
There's probably a better way to do this, but this has been working for me:
// Look through all potential workflows for the correct one:
foreach (Microsoft.SharePoint.Workflow.SPWorkflowAssociation flowAssoc in SPContext.Current.Web.Lists["YourListName"].WorkflowAssociations) {
if (flowAssoc.Enabled && flowAssoc.AllowManual && (flowAssoc.Name.Trim() == workflowNameToLookFor.Trim())) {
// Start the workflow on the current item:
SPContext.Current.Site.WorkflowManager.StartWorkflow(SPContext.Current.Web.Lists["YourListName"].Items[itemIndex], flowAssoc, flowAssoc.AssociationData, true);
}
}

Related

SharePoint Expiration Policy does not fire ItemDeleting Event Receiver

We have attached an ItemDeleting event receiver to a list that requires certain maintenance to be performed in other lists whenever an item is deleted. It works fine when an item is manually deleted by a user. However, if an item is deleted as a result of the Information Management Policy we have defined to delete expired items, the ItemDeleting handler is not executing. Is this standard MOSS behavior? If so, are there any suggested workarounds?
I would run a custom workflow using the policy, there you can define your own logic, which is what you probably try to achieve

UpdateListItem method and System Account

I've developed a Help Desk application in Visual Studio that uses a Sharepoint List to store the data.
My problem is that when i use the UpdateListItems method for submitting a new record, Sharepoint automatically assigns to the "Created By" (Author) field as "System Account" and this prevents the trigger of a workfow i created with Sharepoint Designer.
I've tried to force the Created By field during submit by adding to my batch person id;#person username
but it will still show "System Account"!!
Any ideas!?
sorry for my bad english:(
Have you considered using impersonation to update the list item?
You need a user on the site who has the correct access that you can impersonate. Look into the SPSite constructor that gets passed in an SPUserToken.
SPUserToken token = targetWeb.AllUsers["BobTheImpersonationAccount"].UserToken;
using(SPSite impersonatedSite = new SPSite("http://siteurl", token))
{
//Anything accessed through impersonatedSite and its child objects are now executing under the guise of BobTheImpersonationAccount
}
Option 1: "Update the workflow"
I would not recommend trying to change the Created By field. Instead, create a new People
field (named Submitter or something) in your list and populate that with the user. The workflow should use the Submitter field instead of Created By.
Option 2: "Update your code"
If your workflow, can't be updated, then you'll have to change your code. Instead of submitting using the Service Account, you will need to submit using the credentials of the current user. This means that they will need to have the correct permissions to the list. I am not sure if your code is in a web part or not, so I can't really be more specific.

Setting up a weekly digest in Sharepoint

I'm currently working on a MOSS 2007 site and i need to set up a "system" which will e-mail all the changes in all the lists and libraries in the site.
I'm new to the Sharepoint world, i wonder if it is possible.
P.S. I have no access to the Central Administration panel. (If it has anything to do with my purpose)
Thanks
You can write custom timer job to do this task.
You could do it in this way:
Create custom timer job feature, set timerjob schedule.
On FeatureActivated event add that timerjob to SharePoint and have a [Persisted] property like SiteUrl in timerjob, which you could pass in constructor to let timerjob determine with which site to work with.
Use SPWeb.SiteUsers to get all users in SharePoint.
Loop each user, open new SPSite impersonated as each user.
On SPSite.RootWeb (SPWeb) execute GetSiteData (read community comments for some great examples and explanation on how to use it). Use Query that queries items where Modified field has value greater than (follow link for important info to query correctly) what you want.
Generate html out of your data and SPUtility.SendMail.
There is a scheduled reminder job feature available. However it works only on 1 List scope. But you can download source code, open RmdJobDefinition class and just see how it works to assist you writing your own class.
Good luck.
I'm afraid you can only setup the alert on a list (or item) basis. In the list you go to Actions => Alerts => When to send alerts => Weekly. I didn't check the Central Admin since you don't have access in your scenario.

Setting ModerationInformation.Status from Approved back to pending removes

Seeing if anyone else has had this problem and a resolution to it.
I have a visual studio sequential workflow on a list (not a library) which does NOT use tasks, the approval process is done through the Approve/Reject OOTB buttons on the list item. The approval is a 2 stage approval, whereby if the 1st stage is completed (via clicking the Approve OOTB button), i reset the ModerationInformation.Status from Approved back to pending then send an email to the 2nd stage approver.
My problem is, when i set the the ModerationInformation.Status back to Pending from Approved so there is never an approved version, the Creator loses permissions to view the item, and i get the "cannot find item" error from SharePoint for the person who created the item. The 1st and 2nd level approvers and anyone with approve rights CAN still see the item.
Some more background information. the code i am using to update the moderationinformation is
I get the properties from the workflow event and get a hook into the listitem
properties.Item.ModerationInformation.Status = SPModerationStatusType.Pending;
properties.Item.Update();
can anyone help.
Try using properties.Item.SystemUpdate(); this prevents SHarePoint from triggering any attached EventReceivers etc. I've had the same thing happen also. IMHO this is related to the fact that the item goes into update mode, then SharePoint basically has taken control over the item (seeing as workflows are usually run as the System account) but still sends you back to the the return url (i.e. the EditItem page of the list).
Since SharePoint is probably still doing work on the item (and when you use item.Update() it goes through all events etc. etc.) you cannot open it anymore, because you are not the system account.
When SharePoint finishes (after sent the emails etc.) the item is accessible by users again.
Like I said, I had the same thing happen during long running (i.e. longer than 2 to 3 seconds) EventReceivers / Workflows.

How to access the uiserID of the user who initiated a workflow

DUPE: See link below
I have a SharePoint Designer workflow and I need to send an email to the user who initiated the workflow. It is set for manual start only so it should always be running in the context fo a particular user.
I cannot see a SharePoint Designer action to let me do this, only to get the user who created the list item or by accessing the 'Modified By' column on the list. Neother of these is guaranteed to be the user who is calling the workflow.
Found the same question posted before. It appears to not be possible but the code for a custom workflow activity can be found here.

Resources