我最近将SharePoint 2010的站点迁移到SharePoint 2013,从那时起,我的自定义工作流程在Visual Studio中开发的,在迁移后突然在没有一只故障的情况下完美地工作,它开始抛出这个例外。

w3wp.exe (0x4D3C)                           0x10F0  SharePoint Foundation           Legacy Workflow Infrastructure  88xr    Unexpected
WinWF Internal Error, terminating workflow Id# 21492445-9c27-479c-ae16-5d0d3ae84b69 

w3wp.exe (0x4D3C)                           0x10F0  SharePoint Foundation           Legacy Workflow Infrastructure  98d4    Unexpected
Microsoft.SharePoint.SPException: Cannot complete this action.  Please try again. ---> System.Runtime.InteropServices.COMException: Cannot complete this action.  
Please try again.<nativehr>0x80004005</nativehr><nativestack></nativestack>     
at Microsoft.SharePoint.Library.SPRequestInternalClass.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bPreserveItemUIVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bUnRestrictedUpdateInProgress, Boolean bMigration, Boolean bPublish, String bstrFileName, ISP2DSafeArrayWriter pListDataValidationCallback, ISP2DSafeArrayWriter pRestrictInsertCallback, ISP2DSafeArrayWriter pUniqueFieldCallback)     
at Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bPreserveItemUIVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bUnRestrictedUpdateInProgress, Boolean bMigration, Boolean bPublish, String bstrFileName, ISP2DSafeArrayWriter pListDataValidationCallback, ISP2DSafeArrayWriter pRestrictInsertCallback, ISP2DSafeArrayWriter pUniqueFieldCallback)     
--- End of inner exception stack trace ---     
at Microsoft.SharePoint.SPGlobal.HandleComException(COMException comEx)     
at Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bPreserveItemUIVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bUnRestrictedUpdateInProgress, Boolean bMigration, Boolean bPublish, String bstrFileName, ISP2DSafeArrayWriter pListDataValidationCallback, ISP2DSafeArrayWriter pRestrictInsertCallback, ISP2DSafeArrayWriter pUniqueFieldCallback)     
at Microsoft.SharePoint.SPListItem.AddOrUpdateItem(Boolean bAdd, Boolean bSystem, Boolean bPreserveItemVersion, Boolean bNoVersion, Boolean bMigration, Boolean bPublish, Boolean bCheckOut, Boolean bCheckin, Guid newGuidOnAdd, Int32& ulID, Object& objAttachmentNames, Object& objAttachmentContents, Boolean suppressAfterEvents, String filename, Boolean bPreserveItemUIVersion)     
at Microsoft.SharePoint.SPListItem.UpdateInternal(Boolean bSystem, Boolean bPreserveItemVersion, Guid newGuidOnAdd, Boolean bMigration, Boolean bPublish, Boolean bNoVersion, Boolean bCheckOut, Boolean bCheckin, Boolean suppressAfterEvents, String filename, Boolean bPreserveItemUIVersion)     
at Microsoft.SharePoint.SPListItem.Update()     
at ProductList.AutoApprovalProcess.ApprovalWorkflow.AuthorizeItem()     
at ProductList.AutoApprovalProcess.ApprovalWorkflow.onWorkflowActivated1_Invoked(Object sender, ExternalDataEventArgs e)     
at System.Workflow.ComponentModel.Activity.RaiseGenericEvent[T](DependencyProperty dependencyEvent, Object sender, T e)     
at System.Workflow.Activities.HandleExternalEventActivity.RaiseEvent(Object[] args)     
at System.Workflow.Activities.HandleExternalEventActivity.Execute(ActivityExecutionContext executionContext)     
at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(T activity, ActivityExecutionContext executionContext)     
at System.Workflow.ComponentModel.ActivityExecutorOperation.Run(IWorkflowCoreRuntime workflowCoreRuntime)     
at System.Workflow.Runtime.Scheduler.Run()
.

我看了我的代码,看看apploverworkflow.authorizeItem()究竟究竟发生了什么,然后它没有什么真正的花哨,这是它做的

private void AuthorizeItem()
{
    workflowProperties.Item.ModerationInformation.Status = SPModerationStatusType.Approved;
    workflowProperties.Item.Update();
}
.

基本上工作流程只需自动根据它达到的某个条件批准该项目。然后我在工作流程中看到的是这个

它由ActivityExceutionStatus抛出

protected override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
{
    ((ISharePointService)executionContext.GetService(typeof(ISharePointService))).LogToHistoryList(base.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, 0, TimeSpan.MinValue, string.Empty, string.Format("WorkFlow Exception!: {0}", exception.Message), string.Empty);
    return ActivityExecutionStatus.Closed;
}
.

注意事项每当调用工作流时都不会发生这种情况,它会在偶尔发生时发生,我不知道什么触发

有没有人有想法是什么原因,以及如何阻止它再次发生?

更新1下面添加的实际代码,以获得清晰度

public Guid workflowId = default(System.Guid);
public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
pblic enum ThresholdItem { MultipleThreshold, NoThreshold, BelowThreshold, AboveThreshold, Valid };

private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
    switch (ThresholdCheck())
    {
        case ThresholdItem.Valid:
            AuthorizeItem();
            break;
        case ThresholdItem.BelowThreshold:
            RequestDenied("Below Threshold");
            break;
        case ThresholdItem.AboveThreshold:
            RequestDenied("Above Threshold");
            break;
        case ThresholdItem.NoThreshold:
            RequestDenied("No Threshold Defined");
            break;
        case ThresholdItem.MultipleThreshold:
            RequestDenied("Multiple Threshold Defined");
            break;
    }
}   


private ThresholdItem ThresholdCheck()
{
    SPLinqDataContext dc = new SPLinqDataContext(workflowProperties.SiteUrl + "/Testing");

    EntityList<ThresholdsItem> PriceThreshold = dc.GetList<ThresholdsItem>("Thresholds");

    string destination = GetLinkedListItemString(workflowProperties.Item["Destination"].ToString());
    string origin = GetLinkedListItemString(workflowProperties.Item["Origin"].ToString());
    double price = double.Parse(workflowProperties.Item["Price"].ToString());

    var Result = (from p in Threshold
                    where
                        p.Destination.Title == destination &&
                        p.Origin.Title == origin
                    select p);
    switch (Result.Count())
    {
        case 1:
            var SingleResult = Result.SingleOrDefault();
            if (SingleResult.MinPrice > price)
                return ThresholdItem.BelowThreshold;
            else if (SingleResult.MaxPrice < price)
                return ThresholdItem.AboveThreshold;
            else
                return ThresholdItem.Valid;
        case 0:
            return ThresholdItem.NoThreshold;

        default:
            return ThresholdItem.MultipleThreshold;

    }
}

private void RequestDenied(string note)
{
    workflowProperties.Item.ModerationInformation.Status = SPModerationStatusType.Denied;
    workflowProperties.Item.ModerationInformation.Comment = note;
    workflowProperties.Item.Update();
}

private string GetLinkedListItemString(string item)
{
    if (item.Contains("#"))
    {
        return sItem.Substring(item.LastIndexOf("#") + 1);
    }
    else
    {
        return item;
    }
}
.

有帮助吗?

解决方案 2

Ok it seems like I found the issue and it is in the code itself if you read it closely. Hopefully this solution would help someone in the future.

What happens is that the workflow goes on a multiple loop, this happens when the user updates the list item, it triggers to run the workflow. What happens next is that the Workflow Worker Thread moderates the item and set it to approved, this in turn again triggers the workflow, then it goes again and again until SharePoint decides to terminate it? (not sure yet how but I notice it only runs 10 times). What I noticed is that Sharepoint 2010 handles it very well but Sharepoint 2013 does not and throws and exception once in a while.

If you look at the image it run 10 times (the red highlighted item) before but after fixing it, I tried it twice and now it runs as expected (the blue and green highlighted items).

So whats the fix for the update process not to trigger the workflow again and I had done that by following this solution: https://stackoverflow.com/a/2468156/412519

then change my Updates to

workflowProperties.Item.Update(true);

enter image description here

其他提示

I'm not quite sure if this applies to your case, but if this is a declarative workflow that is using a custom activity that you've developed in VS, then the workflow will run under the same privileges as the initiator of the workflow (ie, the person adding the item to be approved).

You can validate this here: Declarative Workflows and User Context

The basic thing to remember is that declarative workflows (the one’s created by SharePoint Designer) always run impersonating the user who started the workflow. So if I’m a contributor and I make an edit to a list item and that triggers a workflow then that workflow runs as me and has the ability to do everything that I do. Where this can get challenging is in cases where the workflow tries to do something I couldn’t do on my own, like make a change to a list I don’t have permissions to, since it also has the same limitations I do.

If the user does not have permission to set the moderation status this would throw an exception. The permission level needed is "Approve List Items" (SPBasePermissions.ApproveItems). That could explain why it only occurs some of the time. Maybe the user permissions were not quite preserved in the migration? Taking a stab in the dark without knowing more information, but the code in your AuthorizeItem() function is pretty succinct.

许可以下: CC-BY-SA归因
scroll top