惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CXSECURITY Database RSS Feed - CXSecurity.com
Security Latest
Security Latest
V
Vulnerabilities – Threatpost
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
L
LINUX DO - 最新话题
N
News and Events Feed by Topic
P
Proofpoint News Feed
G
GRAHAM CLULEY
NISL@THU
NISL@THU
S
Securelist
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Schneier on Security
Schneier on Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Threat Research - Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tenable Blog
Google DeepMind News
Google DeepMind News
Hacker News - Newest:
Hacker News - Newest: "LLM"
Help Net Security
Help Net Security
C
CERT Recently Published Vulnerability Notes
T
The Exploit Database - CXSecurity.com
I
Intezer
阮一峰的网络日志
阮一峰的网络日志
AI
AI
PCI Perspectives
PCI Perspectives
Hacker News: Ask HN
Hacker News: Ask HN
aimingoo的专栏
aimingoo的专栏
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
腾讯CDC
The Cloudflare Blog
Spread Privacy
Spread Privacy
Latest news
Latest news
有赞技术团队
有赞技术团队
D
Docker
Cyberwarzone
Cyberwarzone
L
LINUX DO - 热门话题
S
Secure Thoughts
Hugging Face - Blog
Hugging Face - Blog
K
Kaspersky official blog
M
MIT News - Artificial intelligence
N
News | PayPal Newsroom
H
Hackread – Cybersecurity News, Data Breaches, AI and More
S
SegmentFault 最新的问题
J
Java Code Geeks
S
Security Affairs
The Register - Security
The Register - Security
云风的 BLOG
云风的 BLOG
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

博客园 - freeliver54

Microsoft Certified: Agentic AI Business Solutions Architect AB-100考试学习指南:智能体AI业务解决方案架构师 Microsoft Certified: AI Agent Builder Associate AB-620 AI 代理构建者助理级认证 [引]深港澳金融科技师 [转]个人金融信息保护技术规范 [引]langchain docs 文档 [转]Assessing Claude Mythos Preview’s cybersecurity capabilities 华为2025年年度报告 Power Platform Release Notes Planner 字节 TRAE 智能编码助手 通义灵码 Python Chroma 相关命令 国内网络环境下 MiniConda + Jupyter + ChromaDB 安装教程 [转]ITIL4有哪些内容 - 洛恺辰 [转]招聘总提 ITIL4 却不懂?搞懂它,IT 再也不用当 “背锅侠 DeepSeek 提取 交易所网站核心500词汇(名词与术语) [引]阿里 无影 Agent 开发套件 AgentBay [转]Register an application [转]Adobe Marketo 向 Azure 註冊應用程式,以取得用戶端 ID/應用程式 ID [引]Regenerate the SAS key used in HTTP trigger flows [引] Azure 服务 [转]学习指南 - PL-600:Microsoft Power Platform 解决方案架构师 软件开发人员 赋能自身 的 能力前展和后延 [转]Power Apps component framework (PCF) 手把手入门实例 [转]Power Apps Standards: Naming Conventions
[转]Power Apps Dataverse Tutorial: Write and register a plug-in
freeliver54 · 2025-09-11 · via 博客园 - freeliver54

本文转自:Tutorial: Write and register a plug-in (Microsoft Dataverse) - Power Apps | Microsoft Learn

Tutorial: Write and register a plug-in

  • 02/14/2025

This tutorial guides you through writing a plug-in and registering it with Microsoft Dataverse. You should first read the Write a plug-in article to familiarize yourself with writing a plug-in.

You can find the complete plug-in solution files for this tutorial here: Sample: Create a basic plug-in.

Goal

Create an asynchronous plug-in registered on the "Create" message of the account table. The plug-in creates a task activity that reminds the creator of the account to follow up one week later.

 Note

This goal can be easily achieved using a workflow without writing code. We are using this simple example so that we can focus on the process of creating and deploying a plug-in.

Prerequisites

  • A System User account with the Administrator or System Customizer role in the target Microsoft Dataverse environment.
  • A model-driven app that includes the account and task tables.
  • Visual Studio 2019 (or later version).
  • Knowledge of the Visual C# programming language.
  • Plug-in Registration tool installed on the development computer. See Dataverse development tools.

Create a plug-in project

This article demonstrates using Visual Studio to write the plug-in and build the assembly. However, you could use your favorite editor for coding and use MSBuild to build the assembly. In either case, you must use the Plug-in Registration tool to register the plug-in with Dataverse.

Alternately, you can use Power Platform CLI to quickly create a new project with boilerplate plug-in code using the command pac plugin init. You would still use the Plug-in Registration tool to register the plug-in with Dataverse.

Another alternative is to use the Power Platform Tools extension as described here: Create and register a plug-in package using Visual Studio. In this case, the extension can create and register the plug-in so the Plug-in Registration Tool isn't needed.

Create a Visual Studio project for the plug-in

  1. Open Visual Studio and open a new Class Library (.NET Framework) project using .NET Framework 4.6.2

    Open a new class library (.NET Framework) project using .NET Framework 4.6.2.

    The name used for the project is also the name of the assembly. This tutorial uses the name BasicPlugin.

  2. In Solution Explorer, right-click the project and select Manage NuGet Packages… from the context menu.

    Manage NuGet packages.

  3. Select Browse and search for Microsoft.CrmSdk.CoreAssemblies and install the latest version.

    Install Microsoft.CrmSdk.CoreAssemblies NuGet Package.

  4. You must select I Accept in the License Acceptance dialog.

     Note

    Adding the Microsoft.CrmSdk.CoreAssemblies NuGet package will include these assemblies in the build folder for your assembly, but you will not upload these assemblies with the assembly that includes your logic. These assemblies are already present in the sandbox runtime.

    Ensure only assemblies referenced directly by your project or through NuGet dependency chains are located in your build folder. You cannot include other assemblies when you register the assembly with your logic. You cannot assume that the assemblies other than those included in the Microsoft.CrmSdk.CoreAssemblies NuGet package will be present on the server and compatible with your code.

  5. In Solution Explorer, right-click the Class1.cs file and choose Rename in the context menu.

    Rename class.

  6. Rename the Class1.cs file to FollowupPlugin.cs.

  7. When prompted, allow Visual Studio to rename the class to match the file name.

    Confirm rename dialog.

Edit the class file to define a plug-in

  1. Add the following using statements to the top of the FollowupPlugin.cs file.

    using System.ServiceModel;  
    using Microsoft.Xrm.Sdk;
    
  2. Implement the IPlugin interface by editing the class.

     Note

    If you just type : IPlugin after the class name, Visual Studio will auto-suggest implementing a stub for the Execute Method.

    public class FollowupPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            throw new NotImplementedException();
        }
    }
    
  3. Replace the contents of the Execute method with the following code.

// Obtain the tracing service
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));

// Obtain the execution context from the service provider.  
IPluginExecutionContext context = (IPluginExecutionContext)
    serviceProvider.GetService(typeof(IPluginExecutionContext));

About the code

Add business logic

The plug-in creates a task activity that reminds the creator of the account to follow up one week later.

Add the following code to the try block. Replace the comment // Plug-in business logic goes here with the following code.

// Create a task activity to follow up with the account customer in 7 days. 
Entity followup = new Entity("task");

followup["subject"] = "Send e-mail to the new customer.";
followup["description"] =
    "Follow up with the customer. Check if there are any new issues that need resolution.";
followup["scheduledstart"] = DateTime.Now.AddDays(7);
followup["scheduledend"] = DateTime.Now.AddDays(7);
followup["category"] = context.PrimaryEntityName;

About the code

  • This code uses the late-bound style to create a task and associate it with the account being created. More information: Create tables using the SDK for .NET
  • Early bound classes can be used, but their use requires generating the classes for the tables and including the file defining those classes with the assembly project. Use of early-bound classes is mostly a personal preference, so those steps are left out of this tutorial for brevity. More information: Late-bound and early-bound programming using the SDK for .NET
  • The Id of the account being created is found in the context OutputParameters and set as the regardingobjectid lookup column for the task.

Build plug-in

In Visual Studio, press F6 to build the assembly. Verify that it compiles without error.

Sign the plug-in

  1. In Solution Explorer, right-click the BasicPlugin project and in the context menu select Properties.

    Open project properties.

  2. In the project properties, select the Signing tab and select the Sign the assembly checkbox.

    Sign the assembly.

  3. In the Choose a strong name key file: dropdown, select <New…>.

  4. In the Create Strong Name Key dialog, enter a key file name, and deselect the Protect my key file with a password checkbox.

  5. Select OK to close the Create Strong Name Key dialog.

  6. In the project properties Build tab, verify that the Configuration is set to Debug.

  7. Press F6 to build the plug-in again.

  8. Using windows explorer, find the built plug-in at: \bin\Debug\BasicPlugin.dll.

 Note

Build the assembly using Debug configuration because you will use the Plug-in Profiler to debug it in a later tutorial. Before you include a plug-in with your solution, you should build it using the release configuration.

Register plug-in

To register a plug-in, you'll need the Plug-in Registration tool.

Connect using the Plug-in Registration tool

  1. Open the Plug-in Registration tool by executing the PAC CLI pac tool prt command.

  2. Select +Create new connection to connect to your Dataverse environment.

  3. Make sure Office 365 is checked.

  4. If you are connecting using a Microsoft account other than one you are currently using, select Show Advanced and enter your credentials. Otherwise, leave Sign-in as current user selected.

     Note

    If your user account employs multifactor authentication (MFA), make sure the Show Advanced checkbox isn't checked.

  5. If your Microsoft Account provides access to multiple environments, select Display list of available organizations.

    Logging in with the Plug-in registration tool.

  6. Select Login.

  7. If you selected Display list of available organizations, select the organization you would like to connect to and select Login.

  8. After you're connected, you'll see any existing registered plug-ins, custom workflow activities, and data providers.

    View existing plug-ins an custom workflow activities.

Register your assembly

  1. In the Register drop-down, select New Assembly.

    Register new assembly.

  2. In the Register New Assembly dialog, select the ellipses (…) button and browse to the assembly you built in the previous step.

    Register new assembly dialog.

  3. For Microsoft 365 users, verify that the isolation mode is set to sandbox and the location to store the assembly is Database.

     Note

    Other options for isolation mode and location apply to on-premises Dynamics 365 deployments. For the location, you can specify the D365 server's database, the server's local storage (disk), or the server's Global Assembly Cache. For more information, see Plug-in storage.

  4. Click Register Selected Plug-ins.

  5. You'll see a Registered Plug-ins confirmation dialog.

    Registerd plug-ins confirmation dialog.

  6. Select OK to close the dialog and close the Register New Assembly dialog.

  7. You should now see the (Assembly) BasicPlugin assembly, which you can expand to view the (Plugin) BasicPlugin.FollowUpPlugin plugin.

    (Plugin) BasicPlugin.FollowUpPlugin plugin.

Register a new step

  1. Right-click the (Plugin) BasicPlugin.FollowUpPlugin and select Register New Step.

    Register a new step.

  2. In the Register New Step dialog, set the following fields.

    SettingValue
    Message Create
    Primary Entity account
    Event Pipeline Stage of Execution PostOperation
    Execution Mode Asynchronous

    Entering relevant step data.

  3. Select Register New Step to complete the registration and close the Register New Step dialog.

  4. You can now see the registered step.

    View the registered step.

 Note

At this point the assembly and steps are part of the system Default Solution. When creating a production plug-in, you would add them to the unmanaged solution that you will distribute. These steps are not included in this tutorial. For more information, see Add your assembly to a solution and Add step to solution .

Test plug-in

  1. Open a model-driven app and create an account table.

  2. Within a short time, open the account and you can verify the creation of the task.

    Account table record with related task activity create by plug-in.

What if the task wasn't created?

Because we are working with an asynchronous plug-in, the operation to create the task occurs after the account is created. Usually, the task creation happens immediately, but if it doesn't you may still be able to view the system job in the queue waiting to be applied. This step registration used the Delete AsyncOperation if StatusCode = Successful option, which is a best practice. This means as soon as the system job completes successfully, you'll not be able to view the system job data unless you re-register the plug-in with the Delete AsyncOperation if StatusCode = Successful option unselected.

However, if there was an error, you can view the system job to see the error message.

View System jobs

Use the Dynamics 365 --custom app to view system jobs.

  1. In your model-driven app, navigate to the app.

    view the dynamics 365 custom app.

  2. In the Dynamics 365 --custom app, navigate to Settings > System > System Jobs.

    navigate to system jobs.

  3. When viewing system jobs, you can filter by Table (Entity). Select Account.

    Filter on accounts.

  4. If the job failed, you should see a record with the name BasicPlugin.FollowupPlugin: Create of account.

    Failed system job.

  5. If you open the system job, you can expand the Details section to view the information written to the trace and details about the error.

    system job details.

Query System jobs

You can use the following Web API query to return failed system jobs for asynchronous plug-ins.

GET <your org uri>/api/data/v9.0/asyncoperations?$filter=operationtype eq 1 and statuscode eq 31&$select=name,message

More information: Query data using the Web API

Or use the following FetchXml:

<fetch top='50' >
  <entity name='asyncoperation' >
    <attribute name='message' />
    <attribute name='name' />
    <filter type='and' >
      <condition attribute='operationtype' operator='eq' value='1' />
      <condition attribute='statuscode' operator='eq' value='31' />
    </filter>
  </entity>
</fetch>

More information: Use FetchXML with FetchExpression

View trace logs

The sample code wrote a message to the trace log. These next steps describe how to view the logs.

By default, plug-in trace logs aren't enabled.

Use the following steps to enable them in a model-driven app.

  1. Open the Dynamics 365 - custom app.

    Open the Dynamics 365 - custom  app.

  2. Navigate to Settings > System > Administration.

    navigate to administration.

  3. In Administration, select System Settings.

  4. In the System Settings dialog, in the customization tab, set Enable logging to plug-in trace log to All.

    System Settings Customization tab.

     Note

    You should disable logging after you are finished testing your plug-in, or at least set it to Exception rather than All.

  5. Select OK to close the System Settings dialog.

  6. Repeat the steps to test your plug-in by creating a new account.

  7. In the Dynamics 365 -- custom app, navigate to Settings > Customization > Plug-In Trace Log.

  8. You should find that a new plug-in trace Log record is created.

    Plug-in trace log record.

  9. If you open the record you might expect that it would include the information you set in your trace, but it doesn't. It only verifies that the trace occurred.

  10. To see the details, it's easier to query this data using the Web API in your browser using the following query with the plugintracelog EntityType, using the typename property to filter results in the messageblock property based on the name of the plug-in class.

    GET <your org uri>/api/data/v9.0/plugintracelogs?$select=messageblock&$filter=typename eq 'BasicPlugin.FollowUpPlugin'

  11. You can expect to see this JSON formatted information returned with the Web API query.

    {
        "@odata.context": "<your org uri>/api/data/v9.0/$metadata#plugintracelogs(messageblock)",
        "value": [{
            "messageblock": "FollowupPlugin: Creating the task activity.",
            "plugintracelogid": "f0c221d1-7f84-4f89-acdb-bbf8f7ce9f6c"
        }]
    }
    

Next steps

In this tutorial, you created a simple plug-in and registered it. Complete Tutorial: Debug a plug-in to learn how to debug this plug-in.

See also

Tutorial: Update a plug-in
Write a plug-in
Register a plug-in
Debug Plug-ins.


Additional resources

Documentation

Training