【发布时间】:2018-12-28 01:02:33
【问题描述】:
我正在关注this 文章以更改我在 c# 插件中的业务流程阶段。我能够将舞台向前移动到下一阶段,但是当我尝试回到前一阶段时收到错误消息。下面的错误是我从 Dynamics 在 UI 中收到的。当我调试插件时,我收到一个不包含任何信息的FaultException<OrganizationServiceFault> 异常。为什么我会收到错误消息?如何修改代码以成功返回到业务流程中的上一个阶段?
错误
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: An unexpected error occurred.
Detail: <OrganizationServiceFault xmlns="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ActivityId>5df51362-b7c1-4817-a8d0-de2d63b15c17</ActivityId>
<ErrorCode>-2147220970</ErrorCode>
<ErrorDetails xmlns:a="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>An unexpected error occurred.</Message>
<Timestamp>2018-07-19T18:55:42.6625925Z</Timestamp>
<ExceptionSource i:nil="true" />
<InnerFault>
<ActivityId>5df51362-b7c1-4817-a8d0-de2d63b15c17</ActivityId>
<ErrorCode>-2147220970</ErrorCode>
<ErrorDetails xmlns:a="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>System.NullReferenceException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #0D309052</Message>
<Timestamp>2018-07-19T18:55:42.6625925Z</Timestamp>
<ExceptionSource i:nil="true" />
<InnerFault i:nil="true" />
<OriginalException i:nil="true" />
<TraceText i:nil="true" />
</InnerFault>
<OriginalException i:nil="true" />
<TraceText i:nil="true" />
</OrganizationServiceFault>
插件
if (localContext == null)
{
throw new ArgumentNullException("localContext");
}
IPluginExecutionContext context = localContext.PluginExecutionContext;
IOrganizationService service = localContext.OrganizationService;
Client client = (Client)service.Retrieve(
Client.LogicalName,
new Guid("75FE165F-848B-E811-80F3-005056B33317"),
new ColumnSet(new String[]{
Client.Properties.ClientId
})
);
client.ChangeStage(service);
改变阶段
public void ChangeStage(IOrganizationService service)
{
// Get Process Instances
RetrieveProcessInstancesRequest processInstanceRequest = new RetrieveProcessInstancesRequest
{
EntityId = this.Id,
EntityLogicalName = this.LogicalName
};
RetrieveProcessInstancesResponse processInstanceResponse = (RetrieveProcessInstancesResponse)service.Execute(processInstanceRequest);
// Declare variables to store values returned in response
int processCount = processInstanceResponse.Processes.Entities.Count;
Entity activeProcessInstance = processInstanceResponse.Processes.Entities[0]; // First record is the active process instance
Guid activeProcessInstanceID = activeProcessInstance.Id; // Id of the active process instance, which will be used later to retrieve the active path of the process instance
// Retrieve the active stage ID of in the active process instance
Guid activeStageID = new Guid(activeProcessInstance.Attributes["processstageid"].ToString());
// Retrieve the process stages in the active path of the current process instance
RetrieveActivePathRequest pathReq = new RetrieveActivePathRequest
{
ProcessInstanceId = activeProcessInstanceID
};
RetrieveActivePathResponse pathResp = (RetrieveActivePathResponse)service.Execute(pathReq);
string activeStageName = "";
int activeStagePosition = -1;
Console.WriteLine("\nRetrieved stages in the active path of the process instance:");
for (int i = 0; i < pathResp.ProcessStages.Entities.Count; i++)
{
// Retrieve the active stage name and active stage position based on the activeStageId for the process instance
if (pathResp.ProcessStages.Entities[i].Attributes["processstageid"].ToString() == activeStageID.ToString())
{
activeStageName = pathResp.ProcessStages.Entities[i].Attributes["stagename"].ToString();
activeStagePosition = i;
}
}
// Retrieve the stage ID of the next stage that you want to set as active
activeStageID = (Guid)pathResp.ProcessStages.Entities[activeStagePosition - 1].Attributes["processstageid"];
// Retrieve the process instance record to update its active stage
ColumnSet cols1 = new ColumnSet();
cols1.AddColumn("activestageid");
Entity retrievedProcessInstance = service.Retrieve("ccseq_bpf_clientsetup", activeProcessInstanceID, cols1);
// Set the next stage as the active stage
retrievedProcessInstance["activestageid"] = new EntityReference(ProcessStage.LogicalName, activeStageID);
service.Update(retrievedProcessInstance);
}
更新
我发现 this 文章解释了如何使用 Web API 更新舞台。当我尝试这种方法时,我得到了错误:
未声明的属性“activestageid”仅在负载中具有属性注释,但在负载中未找到属性值。在 OData 中,只有声明的导航属性和声明的命名流可以表示为没有值的属性。
我尝试了几种“activestageid”,但均未成功(ActiveStageId、_activestageid_value)。
更新 2
根据 Arun 的反馈,我尝试了以下 Web API 调用,但均未成功。我从 ccseq_bpf_clientsetups 表上的 BusinessProcessFlowInstanceId 中提取的 url 中括号内的 ID (ccseq_bpf_clientsetups(###))。我从 ProcessStageBase 表中的 ProcessStageId 中提取的 processstages ID
// Attempt 1
PATCH /COHEN/api/data/v8.2/ccseq_bpf_clientsetups(bc892aec-2594-e811-80f4-005056b33317) HTTP/1.1
{ "ActiveStageID@odata.bind": "/processstages(70018854-db7c-4612-915b-2ad7870a8574)"}
// Attempt 2
PATCH /COHEN/api/data/v8.2/ccseq_bpf_clientsetups(bc892aec-2594-e811-80f4-005056b33317) HTTP/1.1
{ "activestageid@odata.bind": "/processstages(70018854-db7c-4612-915b-2ad7870a8574)"}
// Attempt 3
PATCH /COHEN/api/data/v8.2/ccseq_bpf_clientsetups(bc892aec-2594-e811-80f4-005056b33317) HTTP/1.1
{ "ActiveStageId@odata.bind": "/processstages(70018854-db7c-4612-915b-2ad7870a8574)"}
更新 3
我下载了 jLattimer 的 CRM Rest Builder 并尝试运行他的工具生成的 JavaScript。该代码与我之前编写的代码相同,不幸的是没有工作。在这一点上,我相当有信心在 v8.2 的 Web API 中不支持更改阶段。
【问题讨论】:
-
当前阶段有任何必填字段吗?这可能会阻止您离开活跃阶段
-
@jasonscript 否,当前阶段没有必填字段。我们尝试在完成的 BPF 和不完整的 BPF 上后退一步。在这两种情况下,当前阶段都没有任何必填字段。在 BPF 不完整的情况下,在我们试图退回的上一阶段有一个必填字段,但它确实有一个指定的值
标签: c# plugins dynamics-crm microsoft-dynamics dynamics-crm-2016