DLaB.Xrm.XrmToolBoxTools icon indicating copy to clipboard operation
DLaB.Xrm.XrmToolBoxTools copied to clipboard

Actions are not being generated

Open mariusso opened this issue 3 years ago • 12 comments

Tool and Version EarlyBoundGenerator V 1.2021.12.12

Describe the bug A possible comeback of #284 When I am generating actions against an online environment with interactive login, my actions file is empty. It only contains the namespace. I have a whitelist of 2 actions, rest is empty. If I clear the action whitelist, only the following actions are generated:

  • msdyn_GetCollectionDataRequest
  • msdyn_GetTimelineDataRequest
  • msdyn_JoinProjectTeamRequest
  • msdyn_PostInvoiceRequest
  • msdyn_PostJournalRequest
  • msdyncrm_GetReactionsRequest
  • msdyncrm_GetReactionsResponse

I experience the exact same problem with the same version of the API.

To Reproduce Create actions with the settings from screenshot, select 1 or more actions in the actions whitelist.

Expected behavior A generated file with the actions in the whitelist.

Screenshots image image

mariusso avatar Jan 04 '22 12:01 mariusso

Any chance there is an error in the Output textbox?

daryllabar avatar Jan 04 '22 20:01 daryllabar

Any chance there is an error in the Output textbox?

Well, first there are some errors regarding the auth. I have 2FA on my user so it falls back to interactive login. I'll skip that part of the output. Here is the rest. I pressed the button "Create Actions". The settingss are the same as the screenshot above. And the output is empty.

_Unable to login. Attempting to login using interactive mode. Executing "C:\Users\marius.solend\AppData\Roaming\MscrmTools\XrmToolBox\Plugins\DLaB.EarlyBoundGenerator\crmsvcutil.exe" /url:"https://org.crm4.dynamics.com" /generateActions /out:"C:\Users\marius.solend\AppData\Roaming\MscrmTools\XrmToolBox\Settings\EBG\Actions.cs" /namespace:"Crm.Plugins.EarlyBound" /SuppressGeneratedCodeAttribute /codecustomization:"DLaB.CrmSvcUtilExtensions.Action.CustomizeCodeDomService,DLaB.CrmSvcUtilExtensions" /codegenerationservice:"DLaB.CrmSvcUtilExtensions.Action.CustomCodeGenerationService,DLaB.CrmSvcUtilExtensions" /codewriterfilter:"DLaB.CrmSvcUtilExtensions.Action.CodeWriterFilterService,DLaB.CrmSvcUtilExtensions" /metadataproviderservice:"DLaB.CrmSvcUtilExtensions.BaseMetadataProviderService,DLaB.CrmSvcUtilExtensions" /interactivelogin:true CrmSvcUtil : CRM Service Utility [Version 9.1.0.93] ¸ 2020 Microsoft Corporation. All rights reserved

Begin Reading Metadata Completed Reading Metadata 00:03:32.8756424 Begin Writing File Ensuring Context File is Accessible Writing file Actions.cs to C:\Users\marius.solend\AppData\Local\Temp\tmp6617.tmp Processing 457 OptionSets Wrote 0 OptionSets Processing 1415 Entities Wrote 0 Entities Processing 140 Messages Wrote 124 Messages Code written to C:\Users\marius.solend\AppData\Local\Temp\tmp6617.tmp. Updating File C:\Users\marius.solend\AppData\Roaming\MscrmTools\XrmToolBox\Settings\EBG\Actions.cs Cleaning up Temporary File C:\Users\marius.solend\AppData\Local\Temp\tmp6617.tmp C:\Users\marius.solend\AppData\Local\Temp\tmp6617.tmp Moved To: C:\Users\marius.solend\AppData\Roaming\MscrmTools\XrmToolBox\Settings\EBG\Actions.cs Completed Writing File 00:00:00.0716531 Creation Complete!_

mariusso avatar Jan 05 '22 15:01 mariusso

Two other things to try.

  1. Try using the "Create Actions" button
  2. Try setting up an App User and use that for Auth instead of the 2FA (plus, who wants to deal with manually entering their password)

If that fails that I'll probably need you to give me your EBG config file, as well as the metadata file for the Actions. I'll give you instructions for that if need be.

daryllabar avatar Jan 05 '22 15:01 daryllabar

This was the "Create Actions" button. I have an app user. I'll try that and get back to you. Thanks.

mariusso avatar Jan 05 '22 15:01 mariusso

I now executed the same command line, but with no interactive login. Client id and client secret. Same result. Entities and OptionSets works fine either way. Here is my crmscvutil.exe.config:

<?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings> <!-- crmsvcutil settings --> <add key="language" value="CS" /> <add key="namespace" value="CRM.Plugins.EarlyBound" /> <add key="nologo" value="true" /> <add key="SuppressGeneratedCodeAttribute" value="True" /> <add key="servicecontextname" value="CrmServiceContext" /> <!-- Early Bound Generator settings --> <add key="MaxCrmConnectionTimeOutMinutes" value="20" /> <add key="ActionCommandLineText" /> <add key="ActionPrefixesWhitelist" /> <add key="ActionPrefixesToSkip" /> <add key="ActionsWhitelist" value="ci_CreateAccount|ci_FolkeRegApi" /> <add key="ActionsToSkip" /> <add key="AddDebuggerNonUserCode" value="True" /> <add key="AddNewFilesToProject" value="True" /> <add key="AddOptionSetMetadataAttribute" value="True" /> <add key="CamelCaseClassNames" value="False" /> <add key="CamelCaseMemberNames" value="False" /> <add key="CreateOneFilePerAction" value="False" /> <add key="CreateOneFilePerEntity" value="False" /> <add key="CreateOneFilePerOptionSet" value="False" /> <add key="DeleteFilesFromOutputFolders" value="False" /> <add key="EntityAttributeSpecifiedNames" /> <add key="EntityCommandLineText" /> <add key="EntitiesToSkip" /> <add key="EntitiesWhitelist" value="account|activitypointer|annotation|appointment|bookableresource|businessunit|ci_application|ci_area|ci_ci_application_ci_customerproblems|ci_ci_customerproject_ci_area|ci_ci_customerproject_ci_subsector|ci_ci_inproject_ci_area|ci_ci_inproject_ci_market|ci_ci_inproject_ci_subsector|ci_contactdeliverymembership|ci_contactexternalcontributor|ci_contacttoaccount|ci_coronaform|ci_country|ci_county|ci_customerproblems|ci_customerproject|ci_customerproject_market|ci_deliverymember|ci_document|ci_externalcontributor|ci_inproject|ci_keywordrelation|ci_keywords|ci_lead_ci_area|ci_lead_ci_market|ci_lead_ci_referralparty|ci_market|ci_municipality|ci_opportunity_ci_area|ci_opportunity_ci_market|ci_opportunity_ci_referralparty|ci_opportunity_ci_subsector|ci_person|ci_postalcode|ci_problemsolution|ci_quickdeliverycombination|ci_referralparty|ci_sector|ci_sector_customerproject|ci_sector_lead|ci_sector_opportunity|ci_sparring|ci_subsector|ci_subsector_lead|connection|connectionrole|contact|email|environmentvariabledefinition|environmentvariablevalue|lead|listmember|msdyn_project|msdyn_projectteam|msevtmgt_event|msevtmgt_eventregistration|msevtmgt_registrationresponse|opportunity|opportunityclose|phonecall|post|role|systemuser|systemuserroles|task|team|usersettings" /> <add key="EntityPrefixesToSkip" /> <add key="EntityPrefixesWhitelist" /> <add key="FilePrefixText" /> <add key="GenerateActionAttributeNameConsts" value="False" /> <add key="GenerateAttributeNameConsts" value="True" /> <add key="GenerateAnonymousTypeConstructor" value="True" /> <add key="GenerateConstructorsSansLogicalName" value="False" /> <add key="GenerateEntityRelationships" value="True" /> <add key="GenerateEntityTypeCode" value="False" /> <add key="GenerateEnumProperties" value="True" /> <add key="GenerateOnlyReferencedOptionSets" value="True" /> <add key="GenerateOptionSetMetadataAttribute" value="True" /> <add key="GroupLocalOptionSetsByEntity" value="False" /> <add key="InvalidCSharpNamePrefix" value="_" /> <add key="MakeAllFieldsEditable" value="False" /> <add key="MakeReadonlyFieldsEditable" value="False" /> <add key="MakeResponseActionsEditable" value="False" /> <add key="LocalOptionSetFormat" value="{0}_{1}" /> <add key="OptionSetPrefixesToSkip" /> <add key="OptionSetsToSkip" /> <add key="OptionSetCommandLineText"/> <add key="OptionSetLanguageCodeOverride" /> <add key="OptionSetNames" /> <add key="ProjectNameForEarlyBoundFiles" /> <add key="PropertyEnumMappings" /> <add key="ReadSerializedMetadata" value="False" /> <add key="RemoveRuntimeVersionComment" value="True" /> <add key="ReplaceOptionSetPropertiesWithEnum" value="False" /> <add key="SerializeMetadata" value="False" /> <add key="TokenCapitalizationOverrides" value="AccessTeam|ActiveState|BusinessAs|CardUci|DefaultOnCase|EmailAnd|FeatureSet|IsMsTeams|IsPaiEnabled|IsSopIntegration|MsDyUsd|O365Admin|OnHold|OwnerOnAssign|ParticipatesIn|PartiesOnEmail|PauseStates|SentOn|SlaId|SlaKpi|SyncOptIn|Timeout|UserPuid|VoiceMail|Weblink" /> <add key="UseDeprecatedOptionSetNaming" value="False" /> <add key="UseLogicalNames" value="False" /> <add key="UnmappedProperties" value="duplicaterule:BaseEntityTypeCode,MatchingEntityTypeCode|invoicedetail:InvoiceStateCode|leadaddress:AddressTypeCode,ShippingMethodCode|organization:CurrencyFormatCode,DateFormatCode,TimeFormatCode,WeekStartDayCode|quote:StatusCode|quotedetail:QuoteStateCode|salesorderdetail:SalesOrderStateCode" /> <add key="UseTfsToCheckoutFiles" value="False" /> <add key="WaitForAttachedDebugger" value="False" /> </appSettings> <system.diagnostics> <trace autoflush="true"/> <sources> <source name="Microsoft.Xrm.Tooling.Connector.CrmServiceClient" switchName="Microsoft.Xrm.Tooling.Connector.CrmServiceClient" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="console" type="System.Diagnostics.ConsoleTraceListener"/> <add name="fileListener"/> </listeners> </source> <source name="Microsoft.Xrm.Tooling.CrmConnectControl" switchName="Microsoft.Xrm.Tooling.CrmConnectControl" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="console" type="System.Diagnostics.ConsoleTraceListener"/> <add name="fileListener"/> </listeners> </source> <source name="CrmSvcUtil" switchName="CrmSvcUtil" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="console" type="System.Diagnostics.ConsoleTraceListener"/> <add name="fileListener"/> </listeners> </source> <!-- ADAL Log Source --> <source name="Microsoft.IdentityModel.Clients.ActiveDirectory" switchName="Microsoft.IdentityModel.Clients.ActiveDirectory" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="console" type="System.Diagnostics.DefaultTraceListener" /> <add name="ADALListener" /> </listeners> </source> </sources> <switches> <!--Possible values for switches: Off, Error, Warning, Information, Verbose Verbose: includes Error, Warning, Info, Trace levels Information: includes Error, Warning, Info levels Warning: includes Error, Warning levels Error: includes Error level--> <add name="Microsoft.Xrm.Tooling.CrmConnectControl" value="Error"/> <add name="Microsoft.Xrm.Tooling.Connector.CrmServiceClient" value="Error"/> <add name="CrmSvcUtil" value="Error"/> <add name="Microsoft.IdentityModel.Clients.ActiveDirectory" value="Error" /> </switches> <sharedListeners> <add name="fileListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="CrmSvcUtil.log"/> <add name="ADALListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="ADAL_CrmSvcUtil.log" /> </sharedListeners> </system.diagnostics> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Microsoft.Crm.Sdk" publicKeyToken="31bf3856ad364e35" culture="neutral"/> <bindingRedirect oldVersion="4.0.0.0-9.0.0.0" newVersion="9.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Xrm.Sdk" publicKeyToken="31bf3856ad364e35" culture="neutral"/> <bindingRedirect oldVersion="4.0.0.0-9.0.0.0" newVersion="9.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Xrm.Sdk.Workflow" publicKeyToken="31bf3856ad364e35" culture="neutral"/> <bindingRedirect oldVersion="4.0.0.0-9.0.0.0" newVersion="9.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Crm.Sdk.Proxy" publicKeyToken="31bf3856ad364e35" culture="neutral"/> <bindingRedirect oldVersion="4.0.0.0-9.0.0.0" newVersion="9.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Xrm.Sdk.Deployment" publicKeyToken="31bf3856ad364e35" culture="neutral"/> <bindingRedirect oldVersion="4.0.0.0-9.0.0.0" newVersion="9.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Crm.Workflow" publicKeyToken="31bf3856ad364e35" culture="neutral"/> <bindingRedirect oldVersion="4.0.0.0-9.0.0.0" newVersion="9.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Crm" publicKeyToken="31bf3856ad364e35" culture="neutral"/> <bindingRedirect oldVersion="4.0.0.0-9.0.0.0" newVersion="9.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Xrm.Tooling.Connector" publicKeyToken="31bf3856ad364e35" culture="neutral"/> <bindingRedirect oldVersion="1.0.0.0-99.0.0.0" newVersion="4.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Xrm.Tooling.CrmConnectControl" publicKeyToken="31bf3856ad364e35" culture="neutral"/> <bindingRedirect oldVersion="1.0.0.0-99.0.0.0" newVersion="4.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Xrm.Tooling.Ui.Styles" publicKeyToken="31bf3856ad364e35" culture="neutral"/> <bindingRedirect oldVersion="1.0.0.0-99.0.0.0" newVersion="4.0.0.0"/> </dependentAssembly> </assemblyBinding> </runtime> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/> </startup> </configuration>

Metadata for actions:

<Action Name="ci_CreateAccount"> <Parameter Name="OrganizationNumber" Type="Edm.String" Nullable="false" Unicode="false"/> </Action>

<ComplexType Name="ci_FolkeRegApiResponse"> <Property Name="StatusCode" Type="Edm.Int32"/> <Property Name="SearchResult" Type="Edm.String" Unicode="false"/> <Property Name="Message" Type="Edm.String" Unicode="false"/> </ComplexType> <Action Name="ci_FolkeRegApi"> <Parameter Name="SearchString" Type="Edm.String" Nullable="false" Unicode="false"/> <ReturnType Type="mscrm.ci_FolkeRegApiResponse" Nullable="false"/> </Action>

mariusso avatar Jan 05 '22 17:01 mariusso

Under the Debug tab there is a serialize metadata options: image set that to true, and then in the same folder as the CrmSvcUtil, a large file will get create when you generate the actions. That's the file that I need for the metadata, then I can run that file locally on my machine and see what's going on.

daryllabar avatar Jan 05 '22 19:01 daryllabar

I now tried with an out-of-the-box action whitelisted. Same result. How should i give you the file?

mariusso avatar Jan 06 '22 09:01 mariusso

@daryllabar I put it on my drive. Let me know when you have it.

Link

mariusso avatar Jan 06 '22 16:01 mariusso

I have it. Not sure when I'll be able to test it since I'm going on Holiday.

daryllabar avatar Jan 06 '22 21:01 daryllabar

No worries. It's not an urgent issue. Enjoy your holiday :)

mariusso avatar Jan 07 '22 08:01 mariusso

Can you check this latest version? I tested everything with the custom actions, and it worked for me.

daryllabar avatar Feb 06 '22 19:02 daryllabar

@daryllabar I'm sorry, but it still does not work for me. If don't use a whitelist for prefix or specific actions, then the 7 actions listed in the first post are generated. If I use a whitelist for my prefix or one or more of my custom actions, the file is empty. It only contains the namespace. This was with 1.2022.2.4

mariusso avatar Feb 08 '22 09:02 mariusso

I have the same problem as @mariusso and found the root cause - the error is in the crmsvcutil. To reproduce the error, you need an environment with a lot of entities - in my case, I'm using Dynamics CRM + Omnichannel + Marketing + Portal. The standard method for retrieving action metadata by crmsvcutil (called within IMetadataProviderService.LoadMetadata) retrieves it from the Dataverse using the query:

<fetch>
  <entity name="sdkmessage">
    <attribute name="name" />
    <attribute name="isprivate" />
    <attribute name="sdkmessageid" />
    <attribute name="customizationlevel" />
    <link-entity name="sdkmessagepair" alias="sdkmessagepair" to="sdkmessageid" from="sdkmessageid" link-type="inner">
      <filter>
        <condition alias="sdkmessagepair" attribute="endpoint" operator="eq" value="2011/Organization.svc" />
      </filter>
      <attribute name="sdkmessagepairid" />
      <attribute name="namespace" />
      <link-entity name="sdkmessagerequest" alias="sdkmessagerequest" to="sdkmessagepairid" from="sdkmessagepairid" link-type="outer">
        <attribute name="sdkmessagerequestid" />
        <attribute name="name" />
        <link-entity name="sdkmessagerequestfield" alias="sdkmessagerequestfield" to="sdkmessagerequestid" from="sdkmessagerequestid" link-type="outer">
          <attribute name="name" />
          <attribute name="optional" />
          <attribute name="position" />
          <attribute name="publicname" />
          <attribute name="clrparser" />
          <order attribute="sdkmessagerequestfieldid" descending="false" />
        </link-entity>
        <link-entity name="sdkmessageresponse" alias="sdkmessageresponse" to="sdkmessagerequestid" from="sdkmessagerequestid" link-type="outer">
          <attribute name="sdkmessageresponseid" />
          <link-entity name="sdkmessageresponsefield" alias="sdkmessageresponsefield" to="sdkmessageresponseid" from="sdkmessageresponseid" link-type="outer">
            <attribute name="publicname" />
            <attribute name="value" />
            <attribute name="clrformatter" />
            <attribute name="name" />
            <attribute name="position" />
          </link-entity>
        </link-entity>
      </link-entity>
    </link-entity>
    <link-entity name="sdkmessagefilter" alias="sdmessagefilter" to="sdkmessageid" from="sdkmessageid" link-type="inner">
      <filter>
        <condition alias="sdmessagefilter" attribute="isvisible" operator="eq" value="1" />
      </filter>
      <attribute name="sdkmessagefilterid" />
      <attribute name="primaryobjecttypecode" />
      <attribute name="secondaryobjecttypecode" />
    </link-entity>
    <order attribute="sdkmessageid" descending="false" />
  </entity>
</fetch>

This query, when called in FetchXML Builder with the option to fetch all pages, fetches 50,000 records. But among those first 50,000 records, there are only 130 messages, mostly system ones (Create, Update, Assign and so on) - one record for each message * entity * parameter. And that's exactly how it works in crmsvcutil itself. The workaround I quickly found - instead of generating actions using EBG - I execute crmsvcutil manually in such a way that I remove the metadataproviderservice parameter and add the messagenamesfilter parameter (since recently crmsvcutil natively allows filtering metadata at the level of their download from Dataverse).

Later, I reviewed and extended the code of the BaseMetadataProviderService class so that it was possible to use both native filtering (as a UserArguments in config file) and providers: BaseMetadataProviderService / MetadataProviderService from EBG.

In a few minutes I will create a PR with a proposal for my changes.

majakubowski avatar Jan 12 '23 07:01 majakubowski