Almanac
Microsoft/dataversePower Platform

Consultant KB for Microsoft Dataverse, the data layer under Dynamics 365 and the Power Platform: data model, security model, business logic, APIs and integration, search and queries, analytics and Fabric, ALM and solutions, administration, governance and compliance, and Dataverse as an agent data platform, plus cross-cutting decision guides. Implementation notes, configuration decisions and the gotchas that bite on real projects. Populated by the daily author agent from the Dataverse release plans, docs repo and product blog, plus the author's own consultant notes.

feature-organization-service-sdk.mdv1 · history
CurrentApplies to DeveloperUpdated last monthSource Microsoft Learn

What it does

The .NET client for Dataverse business data and table definitions. You connect through IOrganizationService, build a typed request object such as CreateRequest or RetrieveMultipleRequest, execute it, and get a matching response back. Microsoft's documentation is blunt about its position: the organization service is what defines the platform, and the Web API is a RESTful presentation over the top of it.

Key facts

  • Two NuGet packages. Microsoft.CrmSdk.CoreAssemblies for .NET Framework only — this is what plug-ins and custom workflow activities need. Microsoft.PowerPlatform.Dataverse.Client for .NET Framework or .NET, and that's the one for new client applications.
  • Two implementations of IOrganizationService: ServiceClient and the older CrmServiceClient. Use ServiceClient for anything new; it uses MSAL where CrmServiceClient still uses ADAL, and it has features the older class doesn't. The APIs are close enough that conversion is straightforward.
  • Every operation is a message with a name, and those names are what the event framework binds extensions to. Create, Retrieve, RetrieveMultiple, Update, Delete, Associate, Disassociate plus the specialised ones and anything a custom API adds.
  • ServiceClient and CrmServiceClient handle service protection 429s for you, pausing and resending after the Retry-After duration. Versions of Xrm.Tooling after 9.0.2.16 (May 2019) do this automatically.
  • The 2011 SOAP endpoint is deprecated. Microsoft has said the SDK assemblies will be updated so code keeps working after the endpoint is removed, with new assemblies available before removal. The Web API uses a different endpoint and is unaffected.
  • OrganizationServiceProxy is deprecated. Replace it with ServiceClient.
  • Default request timeout is four minutes on ServiceClient and two minutes on CrmServiceClient, settable via ServiceClient.MaxConnectionTimeout.
  • Early-bound classes are generated with pac modelbuilder build, including request and response classes for custom APIs.

When to use / skip

It's not optional for plug-ins and custom workflow activities — that code must be .NET Framework against the SDK, full stop. For standalone integrations it wins when you want strongly typed code, when you want ExecuteTransaction or ExecuteMultiple without hand-rolling multipart payloads, and when the team is a .NET team and the tooling pays for itself. It loses when the payload size matters, when you don't want a NuGet dependency, or when the caller isn't .NET at all. For a straightforward data integration on a modern stack, the Web API's smaller JSON payloads and lack of client dependency usually make it the better default.

Configuration decisions

  • Which package, which is really a decision about whether the code will ever run inside the sandbox.
  • Connection string authentication type — ClientSecret, Certificate, or an interactive user flow — and where the credential is stored.
  • Whether to generate early-bound classes and check them in, or work late-bound with string keys. Early-bound catches schema drift at compile time; late-bound survives schema changes without regeneration.
  • Whether to reuse a single ServiceClient instance with cloning for parallelism, or create per-thread instances.
  • Request timeout, and whether raising it is actually the right fix or whether the batch is simply too large.

Gotchas

  • Microsoft.CrmSdk.CoreAssemblies targets .NET Framework only. Referencing it from a .NET 8 project compiles further than you'd hope and then fails somewhere inconvenient.
  • Early-bound classes go stale silently. A column rename in a solution and a class file that wasn't regenerated is a runtime error dressed up as a compile-time success.
  • Connection string authentication with a username and password is documented but Microsoft explicitly recommends against it and steers you towards managed identities or app credentials. Use it in a demo, never in delivery.
  • Raising MaxConnectionTimeout to make a bulk operation stop failing usually just moves the failure. Microsoft's own advice is to send fewer records first.
  • Bulk operation messages such as CreateMultiple aren't supported inside plug-in code, and neither are batch request types. That constraint bites when someone tries to be clever in a sandbox.
  • Requests originating inside a plug-in bypass service protection limits entirely, so code that behaves impeccably in the sandbox can hammer the platform when the same class is reused in a console app.

Consultant notes

  • If you inherit a codebase on OrganizationServiceProxy or CrmServiceClient, plan the move to ServiceClient as a small dedicated piece of work rather than folding it into a feature. It's mechanical, and it's much worse when it's urgent.
  • The SOAP endpoint deprecation is a genuine roadmap item to raise with clients running old custom integrations, without dramatising it — the assemblies will be updated first, but somebody has to redeploy them.
  • Set the client's expectation that plug-in code is .NET Framework and will stay that way. Developers who've only worked in modern .NET find this genuinely surprising.
  • For a new integration on a client's own infrastructure, ask whether .NET is actually the requirement or just the habit. The Web API is often the lower-maintenance answer.

Worth revisiting when Microsoft announces the updated SDK assemblies for the SOAP endpoint removal.

Was this accurate?