[英]CRM 2011 Custom Workflow
我進行了插件工作,並且這里更新了工作代碼。 希望能幫助到你!!
我正在創建一個工作流,該工作流的插件可以從電子郵件記錄的“ FROM”字段中檢索聯系人實體。 我正在嘗試查看聯系人實體中是否存在該電子郵件。 輸入是“ FROM”電子郵件,輸出將返回Contacts實體。 我無法使此代碼正常工作,我收到了其他錯誤或沒有錯誤,但我知道它無法正常工作。 請幫忙! 提前致謝!
using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using System;
namespace GetSenderPlugin
{
public class GetSenderPlugin : CodeActivity
{
protected override void Execute(CodeActivityContext executionContext)
{
//Create the tracing service
ITracingService trace = executionContext.GetExtension<ITracingService>();
trace.Trace("*****Tracing Initiated*****");
//Create the IWorkflowContext and the IOrganizationService for communication with CRM
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
trace.Trace("*****IOrganizationService created*****");
trace.Trace("*****Entity logical Name: " + Email.Get<EntityReference>(executionContext).LogicalName + "*****");
trace.Trace("*****Entity ID: " + Email.Get<EntityReference>(executionContext).Id + "*****");
if (Email != null && string.Compare(Email.Get<EntityReference>(executionContext).LogicalName, "email", false) == 0)
{
EntityReference retrieveEmail = new EntityReference();
retrieveEmail.Id = Email.Get<EntityReference>(executionContext).Id;
retrieveEmail.LogicalName = Email.Get<EntityReference>(executionContext).LogicalName;
retrieveEmail.Name = Email.Get<EntityReference>(executionContext).Name;
string[] strArrays = new string[1];
strArrays[0] = "from";
ColumnSet columnSet = new ColumnSet();
columnSet.AddColumn(strArrays[0]);
RetrieveRequest retrieveRequest = new RetrieveRequest();
retrieveRequest.Target = retrieveEmail;
retrieveRequest.ColumnSet = columnSet;
trace.Trace("*****Retrieve Request declared*****");
RetrieveResponse retrieveResponse = (RetrieveResponse)service.Execute(retrieveRequest);
trace.Trace("*****Retrieve Response executed*****");
Email businessEntity = (Email)retrieveResponse.Entity;
trace.Trace("*****businessEnitity retrieved*****");
//ActivityParty activitypartyArray = (ActivityParty)businessEntity.From.FirstOrDefault;
foreach (ActivityParty activityParty in businessEntity.From)
{
trace.Trace("*****Activity Party Name: " + activityParty.PartyId.LogicalName + "*****");
trace.Trace("*****Activity Party Id: " + activityParty.PartyId.Id + "*****");
if (activityParty != null && activityParty != null && activityParty.PartyId != null)
{
string str = activityParty.PartyId.LogicalName;
if (str.CompareTo("contact") != 0)
{
trace.Trace("*****Not Contact*****");
if (str.CompareTo("account") != 0)
{
trace.Trace("*****Not Account*****");
if (str.CompareTo("lead") != 0)
{
trace.Trace("*****Not Lead*****");
if (str.CompareTo("systemuser") != 0)
{
trace.Trace("*****Not System User*****");
if (str.CompareTo("queue") == 0)
{
Queue.Set(executionContext, activityParty.PartyId);
Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid()));
User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid()));
Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid()));
Account.Set(executionContext, new EntityReference("account", Guid.NewGuid()));
}
else
{
trace.Trace("*****User not found*****");
Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid()));
Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid()));
User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid()));
Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid()));
Account.Set(executionContext, new EntityReference("account", Guid.NewGuid()));
}
}
else
{
User.Set(executionContext, activityParty.PartyId);
Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid()));
Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid()));
Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid()));
Account.Set(executionContext, new EntityReference("account", Guid.NewGuid()));
}
}
else
{
Lead.Set(executionContext, activityParty.PartyId);
Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid()));
Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid()));
User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid()));
Account.Set(executionContext, new EntityReference("account", Guid.NewGuid()));
}
}
else
{
Account.Set(executionContext, activityParty.PartyId);
Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid()));
Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid()));
User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid()));
Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid()));
}
}
else
{
trace.Trace("*****Contact assigned*****");
Contact.Set(executionContext, activityParty.PartyId);
Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid()));
User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid()));
Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid()));
Account.Set(executionContext, new EntityReference("account", Guid.NewGuid()));
}
}
break;
}
}
else
{
trace.Trace("*****Email is null*****");
Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid()));
Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid()));
User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid()));
Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid()));
Account.Set(executionContext, new EntityReference("account", Guid.NewGuid()));
}
}
#region Properties
[Input("E-mail")]
[ReferenceTarget("email")]
public InArgument<EntityReference> Email { get; set; }
[Output("Account")]
[ReferenceTarget("account")]
public OutArgument<EntityReference> Account { get; set; }
[Output("Contact")]
[ReferenceTarget("contact")]
public OutArgument<EntityReference> Contact { get; set; }
[Output("Lead")]
[ReferenceTarget("lead")]
public OutArgument<EntityReference> Lead { get; set; }
[Output("Queue")]
[ReferenceTarget("queue")]
public OutArgument<EntityReference> Queue { get; set; }
[Output("User")]
[ReferenceTarget("systemuser")]
public OutArgument<EntityReference> User { get; set; }
#endregion
}
}
因此,我們將內部CRM系統從4.0升級到2011,這是工作流程中的一個插件。 我沒有原始源代碼,所以我真的不知道代碼在做什么。 但是在導出解決方案后,我反編譯了原始的.dll文件。 我試圖重寫CRM 2011的代碼,這就是我所擁有的。 在測試了工作流程之后,出現錯誤消息:“預期的非空Guid”。 代碼進入循環后的最后一行,然后給我錯誤。 這是跟蹤:
Workflow paused due to error: Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Expected non-empty Guid.Detail:
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
<ErrorCode>-2147220989</ErrorCode>
<ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>Expected non-empty Guid.</Message>
<Timestamp>2013-02-21T23:46:37.0376093Z</Timestamp>
<InnerFault>
<ErrorCode>-2147220970</ErrorCode>
<ErrorDetails xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>System.ArgumentException: Expected non-empty Guid.
Parameter name: id</Message>
<Timestamp>2013-02-21T23:46:37.0376093Z</Timestamp>
<InnerFault i:nil="true" />
<TraceText i:nil="true" />
</InnerFault>
<TraceText>[Microsoft.Xrm.Sdk.Workflow: Microsoft.Xrm.Sdk.Workflow.Activities.RetrieveEntity]
[RetrieveEntity]
*****Tracing Initiated*****
*****IOrganizationService created*****
*****Entity logical Name: email*****
*****Entity ID: c49e4c7c-8724-de11-86ce-000c290f83d7*****
*****Retrieve Request declared*****
*****Retrieve Response executed*****
*****businessEnitity retrieved*****
*****Activity Party Name: contact*****
*****Activity Party Id: 79ed3a33-8eb9-dc11-8edd-00c09f226ebb*****
*****Activity Party not null*****
*****Contact assigned*****
*****foreach ended*****</TraceText>
</OrganizationServiceFault>
at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.Retrieve(String entityName, Guid id, ColumnSet columnSet, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType)
at Microsoft.Crm.Extensibility.InprocessServiceProxy.RetrieveCore(String entityName, Guid id, ColumnSet columnSet)
at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.Retrieve(String entityName, Guid id, ColumnSet columnSet)
at Microsoft.Crm.Workflow.Services.RetrieveActivityService.<>c__DisplayClass1.<RetrieveInternal>b__0(IOrganizationService sdkService)
at Microsoft.Crm.Workflow.Services.ActivityServiceBase.ExecuteInTransactedContext(ActivityDelegate activityDelegate)
at Microsoft.Crm.Workflow.Services.RetrieveActivityService.ExecuteInternal(ActivityContext executionContext, RetrieveEntity retrieveEntity)
at Microsoft.Crm.Workflow.Services.RetrieveActivityService.Execute(ActivityContext executionContext, RetrieveEntity retrieveEntity)
at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager)
at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)
我收到了其他錯誤或沒有錯誤,但是我知道它不起作用
首先,我建議您列出問題中的錯誤。 回答您的問題和避免出現-1秒將更加容易。 :)其次,在工作流中使用跟蹤服務。
ITracingService tracingService = context.GetExtension<ITracingService>();
tracingService.Trace("I'm tracing something....");
如果找不到與指定電子郵件的聯系人 ,該怎么辦? 您必須處理這種情況。 可能在這里失敗。 發布有問題的錯誤日志,以進行檢查。
如果我要給出一個發人深省的答案,我想這是問題所在,因為在某些情況下您沒有比賽並過濾掉所有內容。 然后,您在某處得到null (或嘗試引用一個空的 guid,或嘗試選擇一個尚未輸入的屬性,以便盡管已定義該屬性,但仍未提供)。
您得到什么確切的錯誤? 什么時候得到它們,什么時候不得到?
另外,我注意到的一些代碼問題(不是解決方案,但仍可能會得到改善)。
錯字的名字。 我認為您想要ContactReference 。
[Output("output")]
[ReferenceTarget("contact")]
public OutArgument<EntityReference> ContactRefernce { get; set; }
我將以某種不同的方式設計查詢。 由於您知道要匹配的地址,因此您可能希望對其進行精確過濾。 另外,您似乎只需要基於電子郵件的比賽向導,因此您只需要提取該向導即可。
private Guid MatchSenderWithExistingContact(
IOrganizationService service, String fromAddress)
{
QueryExpression query = new QueryExpression
{
EntityName = "contact",
ColumnSet = new ColumnSet("emailaddress1"),
Criteria = new FilterExpression
{
Filters =
{
new FilterExpression
{
Conditions =
{
new ConditionExpression(
"emailaddress1", ConditionOperator.Equal, fromAddress)
}
}
}
}
};
EntityCollection retrieveMultipleRequest = service.RetrieveMultiple(query);
IEnumerable<Entity> entities = retrieveMultipleRequest.Entities;
return entities.FirstOrDefault().Id;
}
您可能希望將查詢的聲明放在逐步語法上。 我更喜歡這種方式,因為它在創建高級查詢時更加方便。 但是,如上所示,當您迭代和使用中斷時,該部分無疑會更好。
編碼愉快!
您可能應該使用該跟蹤。 通常,我在插件類中將跟蹤對象聲明為成員變量,然后在每次操作時將其寫入。 這樣,至少我知道肥料在哪里擊中AC,並且可以在此之前記錄變量的值。
private ITracingService trace;
public void Execute(IServiceProvider serviceProvider)
{
trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
_trace.Trace("Tracing successful!");
throw new Exception("Intentional! Nice.");
}
請記住,除非發生未捕獲的異常,否則不會顯示跟蹤。 實際上,我偶爾會故意使執行崩潰,只是為了查看變量中的內容。 因此請記住,如果您具有全局try-catch ,則需要手動重新引發異常。
這種方法的好處是您可以在內部和在線進行跟蹤。 它適用於除異步之外的所有插件注冊。 也有針對性的解決方法,但這不是您要討論的話題,而且我已經講夠了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.