问题
I have created a workflow is SharePoint Designer and associated it with a list. The workflow creates an approval process, so SharePoint creates a task in the Tasks list so that the user can approve or reject.
What I need to do is to approve or reject the task without opening the task in the task list. After some research I figured that I can use SharePoint Web Services. However I feel lost as I don't know which service, e.g. Lists.asmx, and which method, e.g. UpdateListItems, to call.
Can someone guide me through the following:
1- Is it feasible to approve a workflow task SharePoint Web Services?
2- Can you show me an example of how to approve a task, e.g. which service and method to call and what should be the parameters?
Update
I have been using the following XML to set the workflow to complete:
batchElement.InnerXml = "<Method ID='1' Cmd='Update'>" // Also used Moderate
+ "<Field Name='ID'>115</Field>"
+ "<Field Name='Status'>Completed</Field>"
+ "<Field Name='FormData'>Completed</Field>" // Also used Approved
+ "<Field Name='WorkflowOutcome'>Approved</Field>"
+ "<Field Name='Completed'>True</Field>"
+ "<Field Name='PercentComplete'>1</Field>"
+ "<Field Name='_ModerationStatus'>0</Field>"
+ "</Method>";
The task list item is updated but the WorkflowOutcome remains empty and the workflow doesn't move to the next step.
What else I am missing?
Update #2
I am suspecting the ExtendedProperties of the task list item. For an item that was completed using the UI, the ExtendedProperties shows ws_TaskStatus='Approved'. However for an item that was approved using the code ws_TaskStatus doesn't exist.
Update #3
From an MSDN post, I was told to use the Workflow.asmx instead of the Lists.asmx.
I have used the following code:
WorkflowService.Workflow listProxy = new WorkflowService.Workflow();
listProxy.Url = "http://<server_name>/_vti_bin/workflow.asmx";
listProxy.UseDefaultCredentials = true;
int todoID = 118;
Guid tasklistID = new Guid("{79ABFDE7-0398-4AD7-918A-0D40204E7726}");
string itemURL = "http://<server_name>/TestLibrary/volshext.log";
XmlDocument taskData = new XmlDocument();
taskData.Load(@"..\..\TaskData.xml");
try
{
XmlNode response = listProxy.AlterToDo(itemURL, todoID, tasklistID, taskData.DocumentElement);
Console.WriteLine(response.InnerText);
}
The XML I am using to approve the task is
<my:myFields xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD" >
<my:TaskStatus>#</my:TaskStatus>
<my:Comments />
<my:DelegateTo />
<my:NewDescription>Please approve Workflow Demo</my:NewDescription>
<my:NewDueDate />
<my:RequestTo />
<my:Decline>0</my:Decline>
<my:dcr>0</my:dcr>
<my:Status>Completed</my:Status>
</my:myFields>
But again the task was updated but the workflow didn't move forward.
Update #4
I have made one last trial with SharePoint server object model however, again, the task is updated but the workflow is not moving forward.
Here is my code:
SPSite site = new SPSite("http://sitenamehere/");
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["Shared Documents"];
//SPListItem item = list.GetItemById(18);
SPListItem item = list.GetItemByUniqueId(new Guid("5300d16e-94f8-4338-8206-4a57ab7c369b"));
SPWorkflow workflow = item.Workflows[0];
SPWorkflowTask task = workflow.Tasks[0];
Hashtable ht = new Hashtable();
ht[SPBuiltInFieldId.Completed] = "TRUE";
ht["Completed"] = "TRUE";
ht[SPBuiltInFieldId.PercentComplete] = 1.0f;
ht["PercentComplete"] = 1.0f;
ht["Status"] = "Completed";
ht[SPBuiltInFieldId.TaskStatus] = SPResource.GetString(new CultureInfo((int)task.Web.Language, false), Strings.WorkflowStatusCompleted, new object[0]);
//ht["TaskStatus"] = "#";
//ht["ows_TaskStatus"] = "Approved";
//ht["FormData"] = SPWorkflowStatus.Completed;
//ht["Outcome"] = "Approved";
//task.ModerationInformation.Status = SPModerationStatusType.Approved;
web.AllowUnsafeUpdates = true;
SPWorkflowTask.AlterTask((task as SPListItem), ht, true);
}
回答1:
After a lot of trials and investigation I just had the following code working to approve the task
SPSite site = new SPSite("http://servername/");
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["TestList"];
SPListItem item = list.GetItemById(22);
SPWorkflow workflow = item.Workflows[0];
SPWorkflowTask task = workflow.Tasks[0];
Hashtable ht = new Hashtable();
ht[SPBuiltInFieldId.Completed] = "TRUE";
ht["Completed"] = "TRUE";
ht[SPBuiltInFieldId.PercentComplete] = 1.0f;
ht["PercentComplete"] = 1.0f;
ht["Status"] = "Completed";
ht[SPBuiltInFieldId.TaskStatus] = SPResource.GetString(new CultureInfo((int)task.Web.Language, false), Strings.WorkflowStatusCompleted, new object[0]);
ht[SPBuiltInFieldId.WorkflowOutcome] = "Approved";
ht["TaskStatus"] = "Approved";
ht["FormData"] = SPWorkflowStatus.Completed;
web.AllowUnsafeUpdates = true;
SPWorkflowTask.AlterTask((task as SPListItem), ht, true);
}
I suspect that ht["TaskStatus"] = "Approved";
is that attribute that solved it. Anyway I will try to narrow on the set of properties that need to be changed.
回答2:
You can use the following code that uses the lists web service and the UpdateListItems method. The key is to use the Cmd='Moderate'
public static XmlNode UpdateListItemApprove()
{
listservice.Lists listProxy = new listservice.Lists();
string xml = "<Batch OnError='Continue'><Method ID='1' Cmd='Moderate'><Field Name='ID'/><Field Name='FileRef'>http://basesmcdev2/sites/tester1/approvals/KL022030.lic</Field><Field Name=\"_ModerationStatus\" >0</Field></Method></Batch>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNode batchNode = doc.SelectSingleNode("//Batch");
listProxy.Url = "http://basesmcdev2/sites/tester1/_vti_bin/lists.asmx";
listProxy.UseDefaultCredentials = true;
XmlNode resultNode = listProxy.UpdateListItems("approvals", batchNode);
return resultNode;
}
回答3:
I'm not sure if Madhur's solution works on the associated item or on the task, but to update the task try:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<UpdateListItems
xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<listName>Tasks</listName>
<updates>
<Batch OnError="Continue" ListVersion="1">
<Method ID="1" Cmd="Update">
<Field Name="ID">199</Field>
<Field Name="Outcome">Approved</Field>
<Field Name="Status">Completed</Field>
<Field Name="ows_TaskStatus">Approved</Field>
</Method>
</Batch>
</updates>
</UpdateListItems>
</soap:Body>
</soap:Envelope>
Info on the service:
http://objectmix.com/sharepoint/800144-updatelistitems-web-service-does-not-update-field.html
Info on the approved field:
http://social.msdn.microsoft.com/Forums/en/sharepointworkflow/thread/6712d379-2df6-4223-9a29-b2e60493f1b6
http://social.msdn.microsoft.com/Forums/en/sharepointworkflow/thread/3dc95190-cc61-4067-ac35-2d1a82fad499
来源:https://stackoverflow.com/questions/4814828/approve-a-sharepoint-workflow-task-using-sharepoint-web-services-object-model