2017-02-13 2 views
0

У меня есть что-то, что происходит промежуточно (например, < 1% времени), что я понятия не имею, как это возможно. У меня есть плагин, зарегистрированный в пост-операции события Qualify Lead, и переопределил кнопку Qualify для выполнения запроса Qualify Lead, установив значения CreateAccount, CreateContact и CreateOpportunity в значение false. Затем плагин создает учетную запись, контакт и возможность, а также 4 других потенциальных пользовательских объекта.Учет, который только что был создан, больше не существует в плагине CRM

Ниже приведен соответствующий код:

protected override void ExecuteInternal(ExtendedPluginContext context) 
{ 
    var createdEntities = context.GetOutputParameterValue<EntityReferenceCollection>("CreatedEntities"); 
    var initiatingUser = context.SystemOrganizationService.GetEntity<SystemUser>(context.InitiatingUserId, u => new { u.new_RelatedEmployee, u.FullName }); 
    var initiatingUserEntityRef = initiatingUser.ToEntityReference(); 
    var lead = RetrieveLead(context); 
    CreateAccount(context, lead, initiatingUserEntityRef, createdEntities); 
    CreateContact(context, lead, initiatingUserEntityRef, createdEntities); 
    CreateLocation(context, lead, initiatingUser, createdEntities); 
    CreateSystemPullJob(context, lead, initiatingUserEntityRef, createdEntities); 
    CreateInstallJob(context, lead, initiatingUserEntityRef, createdEntities); 
    CreateOpportunity(context, lead, initiatingUserEntityRef, createdEntities); 
    CreateOpportunityProducts(context, lead, initiatingUserEntityRef, createdEntities); 
    UpdateLead(context, lead, initiatingUser, createdEntities); 
} 

private static void CreateAccount(ExtendedPluginContext context, XrmLead lead, EntityReference initiatingUser, EntityReferenceCollection createdEntities) 
{ 
    if (lead.CustomerId != null) 
    { 
     context.Trace("Account already exists for Lead. Not creating Account."); 
     return; 
    } 

    context.Trace("Creating Account"); 
    var account = context.SystemOrganizationService.InitializeFrom<Account>(lead.ToEntityReference(), TargetFieldType.ValidForCreate); 
    account.OwnerId = initiatingUser; 
    account.ModifiedOnBehalfBy = initiatingUser; 
    account.CreatedOnBehalfBy = initiatingUser; 

    account.Id = context.SystemOrganizationService.CreateWithSupressDuplicateDetection(account); 

    lead.CustomerId = account.ToEntityReference(); 

    createdEntities.Add(account.ToEntityReference()); 
} 

private static void CreateInstallJob(ExtendedPluginContext context, 
            XrmLead lead, 
            EntityReference initiatingUser, 
            EntityReferenceCollection createdEntities) 
{ 
    context.Trace("Creating Install Job"); 
    var job = context.SystemOrganizationService.InitializeFrom<new_job>(lead.ToEntityReference(), TargetFieldType.ValidForCreate); 
    job.new_jobname = "New - Install"; 
    job.new_CustomerId = lead.CustomerId; 
    job.new_LocationId = GetLocation(lead, createdEntities); 
    job.new_JobTypeEnum = new_JobType.Installation; 
    job.OwnerId = initiatingUser; 
    job.ModifiedOnBehalfBy = initiatingUser; 
    job.CreatedOnBehalfBy = initiatingUser; 

    if (lead.new_PreviousLocationId != null) 
    { 
     // Set prerequiste job to system pull job 
     job.new_PrerequisiteJobId = createdEntities.First(e => e.LogicalName == job.LogicalName); 
    } 

    job.Id = context.SystemOrganizationService.CreateWithSupressDuplicateDetection(job); 

    createdEntities.Add(job.ToEntityReference()); 
} 

Учетная запись создается, добавляется в lead.CustomerId, а затем используется для добавления отношения к месту после создания.

По трассировке стеки, ошибка происходит на Сотворении Установки Иова (даже несмотря на то, Контакт уже был создан, а также ссылки как это ParentCustomerId)

Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Account With Id = d14241a1-eef1-e611-810e-e0071b6ac161 Does Not ExistDetail: 
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts"> 
    <ActivityId>05e171b8-60dd-44d5-ba40-42edb79620d8</ActivityId> 
    <ErrorCode>-2147220969</ErrorCode> 
    <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" /> 
    <Message>Account With Id = d14241a1-eef1-e611-810e-e0071b6ac161 Does Not Exist</Message> 
    <Timestamp>2017-02-13T13:16:34.5516854Z</Timestamp> 
    <ExceptionSource>SdkClient</ExceptionSource> 
    <InnerFault> 
     <ActivityId>05e171b8-60dd-44d5-ba40-42edb79620d8</ActivityId> 
     <ErrorCode>-2147220969</ErrorCode> 
     <ErrorDetails xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" /> 
     <Message>Account With Id = d14241a1-eef1-e611-810e-e0071b6ac161 Does Not Exist</Message> 
     <Timestamp>2017-02-13T13:16:34.5516854Z</Timestamp> 
     <ExceptionSource i:nil="true" /> 
     <InnerFault i:nil="true" /> 
     <OriginalException i:nil="true" /> 
     <TraceText i:nil="true" /> 
    </InnerFault> 
    <OriginalException>System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: Account With Id = d14241a1-eef1-e611-810e-e0071b6ac161 Does Not Exist (Fault Detail is equal to Microsoft.Xrm.Sdk.OrganizationServiceFault). 
     at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode, ExecutionContext executionContext) 
     at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType) 
     at Microsoft.Crm.Extensibility.InprocessServiceProxy.ExecuteCore(OrganizationRequest request) 
     at Microsoft.Crm.Sandbox.SandboxSdkListener.ExecuteInternal(SandboxCallInfo callInfo, SandboxSdkContext requestContext, String operation, Byte[] serializedRequest, IExecutionContext context, String&amp; primaryEntityName) 
     at Microsoft.Crm.Sandbox.SandboxSdkListener.Execute(SandboxCallInfo callInfo, SandboxSdkContext requestContext, String operation, Byte[] serializedRequest) 
     Original SdkErrors: 
    </OriginalException> 
    <TraceText>Entered Contoso.Xrm.Lead.Plugins.QualifyLeadLogic.Execute() 
     Contoso.Xrm.Lead.Plugins.QualifyLeadLogic.Execute is Executing for Entity: lead, Message: QualifyLead 
     Creating Account 
     Creating Contact 
     Creating Location 
     Creating Install Job 
     Exception: System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: Account With Id = d14241a1-eef1-e611-810e-e0071b6ac161 Does Not Exist (Fault Detail is equal to Microsoft.Xrm.Sdk.OrganizationServiceFault). 

     Server stack trace: 
     at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc&amp; rpc) 
     at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 
     at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) 
     at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 

     Exception rethrown at [0]: 
     at Microsoft.Crm.Sandbox.SandboxOrganizationService.Execute(String operation, Byte[] serializedRequest, Object sandboxTraceSettingsObj) 
     at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]&amp; outArgs) 
     at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg) 

     Exception rethrown at [1]: 
     at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 
     at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData, Int32 type) 
     at Microsoft.Crm.Sandbox.ISandboxOrganizationService.Execute(String operation, Byte[] serializedRequest, Object traceSettings) 
     at Microsoft.Crm.Sandbox.SandboxOrganizationServiceWrapper.ExecuteInternal(OrganizationRequest request) 
     at DLaB.Xrm.Extensions.CreateWithSupressDuplicateDetection(IOrganizationService service, Entity entity) 
     at Contoso.Xrm.Lead.Plugins.QualifyLeadLogic.CreateInstallJob(ExtendedPluginContext context, Lead lead, EntityReference initiatingUser, EntityReferenceCollection createdEntities) 
     at Contoso.Xrm.Lead.Plugins.QualifyLeadLogic.ExecuteInternal(ExtendedPluginContext context) 
     at DLaB.Xrm.Plugin.GenericPluginHandlerBase`1.ExecuteRegisteredEvent(T context) 
     at DLaB.Xrm.Plugin.GenericPluginHandlerBase`1.Execute(IServiceProvider serviceProvider) 
     **** Context Info **** 
     Plugin: Contoso.Xrm.Lead.Plugins.QualifyLeadLogic 
     * Registered Event * 
     Stage: PostOperation 
     Message: QualifyLead 
     Message Name: QualifyLead 
     Entity Logical Name: 
     Execute: Null 
     BusinessUnitId: 425821ca-d73c-e411-936d-a45d36fd8134 
     CorrelationId: 75366e73-bee1-4154-81a4-354a4c0ffe8f 
     Depth: 1 
     InitiatingUserId: 995e0b19-4592-e611-80f3-5065f38a4951 
     IsInTransaction: True 
     IsolationMode: 2 
     MessageName: QualifyLead 
     Mode: 0 
     OperationCreatedOn: 2/13/2017 1:16:32 PM 
     OperationId: 68ea91c1-3727-4cb4-a52d-3a632b4239e0 
     Organization: org8ea62131(fc3abc92-879c-4a08-8715-4156ce535b92) 
     OwningExtension: Contoso.Xrm.Lead.Plugins.QualifyLead: QualifyLead of lead (3d85ff0c-8705-e611-80ee-3863bb36bd38) 
     PrimaryEntityId: 00000000-0000-0000-0000-000000000000 
     PrimaryEntityName: lead 
     SecondaryEntityName: none 
     UserId: 995e0b19-4592-e611-80f3-5065f38a4951 
     * Input Parameters * 
      Param[CreateAccount]: False 
      Param[CreateContact]: False 
      Param[CreateOpportunity]: False 
      Param[LeadId]: EntityReference { LogicalName: lead, Name: , Id: 122448c6-edf1-e611-810e-e0071b6ac161} 
      Param[SourceCampaignId]: EntityReference { LogicalName: campaign, Name: , Id: 330a11ca-4687-e611-80f3-5065f38b21f2} 
      Param[Status]: 3 
      Param[OpportunityCurrencyId]: 
      Param[OpportunityCustomerId]: 
      Param[ProcessInstanceId]: 
     * Output Parameters * 
      Param[CreatedEntities] Entity Reference Collection: 
       EntityReference { LogicalName: account, Name: , Id: d14241a1-eef1-e611-810e-e0071b6ac161} 
       EntityReference { LogicalName: contact, Name: , Id: dd4241a1-eef1-e611-810e-e0071b6ac161} 
       EntityReference { LogicalName: new__location, Name: , Id: e64241a1-eef1-e611-810e-e0071b6ac161} 
     PostEntityImages: Empty 
     PreEntityImages: Empty 
     * Shared Variables * 
      Param[ChangedEntityTypes]: System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]: 
       [lead, Update] 
      Param[Contoso.Xrm.Lead.Plugins.QualifyLeadLogic|QualifyLead|PostOperation|00000000-0000-0000-0000-000000000000]: 1 
     Has Parent Context: False 
     Stage: 40 
     Exiting Contoso.Xrm.Lead.Plugins.QualifyLeadLogic.Execute() 
    </TraceText> 
</OrganizationServiceFault> 

Server stack trace: 
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) 
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) 
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) 
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 

Exception rethrown at [0]: 
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 
at Microsoft.Crm.Sandbox.ISandboxHost.ExecuteAndReturnTraceInfo(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, String assemblyContents, Boolean returnTraceInfo) 
at Microsoft.Crm.Sandbox.SandboxPlugin.Execute(SandboxClient client, SandboxCallTracker callTracker, IExecutionContext requestContext, String assemblyContents, Boolean returnTraceInfo) 
at Microsoft.Crm.Sandbox.SandboxCodeUnit.Execute(IExecutionContext context) 

Я вижу только два возможно, что учетная запись не была создана для начала (кажется маловероятной, поскольку создание контакта было успешным) или что учетная запись удаляется после создания контакта, но до создания заданий (но я не знаю нигде, что мы выполняем удаления , и я не думаю, что вы можете удалить предприятие в транзакции, вне транзакции ...)

Идеи?

+0

Боковое примечание. Мне нравится ваша сериализация контекста. Это полностью обычай? – Polshgiant

+0

@Polshgiant - это один метод расширения одной линии, расположенный в DLaB.Xrm.dll (доступный через nuget DLaB.Xrm.2015/2016) 'IExtendedPluginContext.GetContextInfo()' или 'IPluginExecutionContext.ToStringDebug()' (https://github.com/daryllabar/XrmUnitTest/blob/master/DLaB.Xrm.Base/Extensions.cs строка 815) – Daryl

+0

Включает ли <1% все исполнения или только исполнения, когда у руководства не было учетной записи, уже назначенной? Я вижу, что условно, но не знаю, что касается бизнеса и использования, я не знаю, как часто это происходит. – Nicknow

ответ

1

Можете ли вы подтвердить, что идентификатор «отсутствующего идентификатора учетной записи» является идентификатором созданной учетной записи? Если вы запрашиваете db для этой учетной записи после возникновения ошибки, я думаю, что она не попала в хит? Вы отметили ошибку «двойной щелчок»? Выдача QualifyLead дважды «одновременно» может, конечно, привести к интересным эффектам, если есть возможное кровотечение между двумя казнями.

+0

Да, согласно журналу ошибок, идентификатор учетной записи был создан идентификатором учетной записи. Запрос для сообщения post error возвращает null, так как транзакция была отброшена. Я проверю ошибку двойного щелчка, но я не думаю, что это плохой фактор, так как он создан на основе alredy ... О, и SystemOrginzationService просто пугает из контекста плагина и не может быть общим (Bleed) из другого плагина ... – Daryl

+0

Можете ли вы уточнить, какая строка кода в createinstalljob вызывает исключение? – keerz

+0

Да @keerz, второй, чтобы продолжить с CreateWithSupressDuplicateDetection – Daryl

0

(Пытался сделать это замечание, так как это технически не ответ, но это было слишком долго.)

Что произойдет, если вы закомментировать создание установки работы? Все ли работает нормально? Создана учетная запись?

Еще одна вещь, которую нужно проверить, - это запросить учетную запись после выполнения каждого из ваших методов create. Помог бы вам сузить, когда аккаунт исчезнет.

Кроме того, что касается вашей заметки об исключении из-за границы транзакции, мое понимание того, как работают транзакции, выглядит следующим образом. То, что вы предлагаете, было бы правдой, если бы удаление произошло от того, что создает свою собственную транзакцию (например, плагин async). Но если удаление произошло из некоторого синхронного плагина при создании контакта, например, тогда этот плагин также будет запущен в транзакции. Если это так, тогда будет разрешено удалить учетную запись.

+0

Контакт можно создать просто отлично, без проблем, поэтому «удалить» произойдет когда-нибудь после его создания, но до создания местоположения. У нас нет логики, которая удаляет контакты. – Daryl

0

Не ответ либо, но слишком долго для комментариев

Так что, если вы хотите сказать, что это) происходит с перерывами и б) не существует никакой другой логики, которая может быть удаление учетной записи, я думаю, единственный вывод для некоторая неизвестная причина времени, создание installjob опережает видимую для него учетную запись. Не знаю, почему это произойдет, но опять же, чтобы сузить дело, вы могли поймать исключение и не подвести сделку. Это, по крайней мере, скажет вам, действительно ли учетная запись действительно создана.Если это так, и основная причина проблемы синхронизации не найдена, вы можете попробовать только создать installjob, если вы уверены, что можете получить учетную запись. Все обходные пути до тех пор, пока не будет устранена дополнительная ошибка.

Другая мысль, может ли это быть связанной с безопасностью? Эта учетная запись не существует, сообщение может действительно означать, что для вас не существует учетной записи. Кажется странным, если пользователь контекста плагина создал его, но, возможно, другие факторы безопасности?

Смежные вопросы