You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Dynamics 365中点击按钮调用C# Web API导出数据

Got it, let’s walk through exactly how to add a button in your Dynamics 365 instance that triggers your existing export API. I’ve tailored these steps to work with the code you already have, so let’s dive in:

Step 1: Deploy Your Web API to a Accessible Host

Right now, your API runs locally in Visual Studio—you need to get it online somewhere Dynamics 365 can reach it. Azure App Service is a straightforward cloud option, but an internal server (on the same network as your Dynamics instance) works too. Before deploying, double-check:

  • Your CrmOnline connection string is correctly configured for the deployed environment (so the API can still talk to your Dynamics instance)
  • You’ve enabled HTTPS (Dynamics requires external services to use secure connections)
  • Test the deployed API directly (with Postman or a browser) to confirm it generates and returns the Excel file successfully
Step 2: Add a Custom Button to Dynamics 365

Next, we’ll add a button to the Activity grid (or form) that users can click to trigger the export. Use the Power Apps Maker Portal for this:

  • Open Power Apps Maker, select your Dynamics 365 environment
  • Go to Solutions, open your target solution (or create a new one to keep changes organized)
  • Find the Activity Pointer entity, then open its Command Bar (choose "Main Grid" if you want the button on the list view, or select a specific form if you want it there)
  • Click New Command and set up the button:
    • Label: Something clear like "Export Activities via API"
    • Icon: Pick an appropriate one (the built-in Excel icon works great)
    • Action: Select JavaScript—this is where we’ll write code to call your API
Step 3: Write the JavaScript to Trigger Your API

Paste this custom script into the JavaScript action field (replace the placeholder API URL with your deployed endpoint):

function callExportAPI() {
    // Replace with your deployed API's actual URL
    const apiUrl = "https://your-deployed-api.azurewebsites.net/api/ExportActivities";
    
    // Show a loading indicator so users know something's happening
    Xrm.Utility.showProgressIndicator("Exporting activities...");
    
    // Call the API (adjust method to POST if your API uses it)
    fetch(apiUrl, {
        method: "GET",
        headers: {
            "Content-Type": "application/json",
            // Add auth headers if your API needs them—e.g., API key or OAuth token
            // "Authorization": "Bearer " + Xrm.Utility.getGlobalContext().userSecurityToken
        }
    })
    .then(response => response.blob())
    .then(blob => {
        // Trigger the browser download for the Excel file
        const downloadUrl = window.URL.createObjectURL(blob);
        const link = document.createElement("a");
        link.href = downloadUrl;
        link.download = "Activities.xlsx";
        document.body.appendChild(link);
        link.click();
        
        // Clean up and notify user
        window.URL.revokeObjectURL(downloadUrl);
        document.body.removeChild(link);
        Xrm.Utility.closeProgressIndicator();
        Xrm.Navigation.openAlertDialog({ text: "Export completed successfully!" });
    })
    .catch(error => {
        Xrm.Utility.closeProgressIndicator();
        Xrm.Navigation.openErrorDialog({ message: `Export failed: ${error.message}` });
        console.error("API call error:", error);
    });
}

Optional: Pass Selected Records

If you want users to export only selected activities instead of the full set, modify the script to send selected record IDs to your API:

// Get selected records from the grid
const selectedRecords = Xrm.Page.getControl("subgrid").getSelectedRecords();
const recordIds = selectedRecords.map(record => record.getId());

// Send IDs via POST to your API
fetch(apiUrl, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ recordIds: recordIds })
})

Don’t forget to update your API to accept and use these IDs in its FetchXml!

Step 4: Convert Your Console App to a Proper Web API

Your existing code is a console app—we need to turn it into an ASP.NET Core Web API so it can handle HTTP requests from Dynamics. Here’s the adjusted version:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Client;
using Microsoft.Xrm.Client.Services;
using Microsoft.Xrm.Sdk;
using System.Configuration;
using System.IO;
using System.Linq;

namespace ActivityExportAPI.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ExportActivitiesController : ControllerBase
    {
        [HttpGet]
        public IActionResult ExportActivities()
        {
            try
            {
                var connection = CrmConnection.Parse(ConfigurationManager.ConnectionStrings["CrmOnline"].ConnectionString);
                using (var orgService = new OrganizationService(connection))
                {
                    var exportRequest = new OrganizationRequest("ExportToExcel");
                    exportRequest.Parameters = new ParameterCollection
                    {
                        {"View", new EntityReference("savedquery", new Guid("{00000000-0000-0000-00AA-000010001902}"))},
                        {"FetchXml", @"<?xml version='1.0'?> <fetch distinct='false' mapping='logical' output-format='xml-platform' version='1.0'> <entity name='activitypointer'> <attribute name='subject'/> <attribute name='ownerid'/> <attribute name='prioritycode'/> <attribute name='regardingobjectid'/> <attribute name='activitytypecode'/> <attribute name='statecode'/> <attribute name='scheduledstart'/> <attribute name='scheduledend'/> <attribute name='activityid'/> <attribute name='instancetypecode'/> <attribute name='community'/> <attribute name='senton'/> <attribute name='statuscode'/> <order descending='false' attribute='scheduledend'/> <filter type='and'> <condition attribute='actualdurationminutes' value='43800' operator='le'/> </filter> <link-entity name='systemuser' alias='activitypointerowningusersystemusersystemuserid' link-type='outer' visible='false' to='owninguser' from='systemuserid'> <attribute name='internalemailaddress'/> </link-entity> <link-entity name='email' alias='email_engagement' link-type='outer' visible='false' to='activityid' from='activityid'><attribute name='isemailfollowed'/> <attribute name='lastopenedtime'/> <attribute name='delayedemailsendtime'/> </link-entity> </entity> </fetch>"},
                        {"LayoutXml", @" <grid name='resultset' object='2' jump='fullname' select='1' icon='1' preview='1'> <row name='result' id='activitypointerid'> <cell name='activitytypecode' width='150' /> <cell name='statecode' width='112' /> <cell name='scheduledstart' width='110' /> <cell name='scheduledend' width='110' /> </row> </grid>"},
                        {"QueryApi", ""},
                        {"QueryParameters", new InputArgumentCollection()}
                    };

                    var exportResponse = orgService.Execute(exportRequest);
                    if (exportResponse.Results.Any())
                    {
                        var excelBytes = exportResponse.Results["ExcelFile"] as byte[];
                        return File(excelBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Activities.xlsx");
                    }
                    return BadRequest("No data available to export");
                }
            }
            catch (FaultException<OrganizationServiceFault> ex)
            {
                return StatusCode(500, $"Dynamics API Error: {ex.Message}");
            }
        }
    }
}

Key changes:

  • Converted to an ASP.NET Core controller that returns a File result (triggers browser download)
  • Removed console-specific code (like Main method and Windows.Forms references)
  • Ensured the connection string is pulled from the deployed app’s config
Step 5: Test the Full Flow
  • Publish your updated Web API to your host
  • Save and publish the custom button in Power Apps Maker
  • Open Dynamics 365, navigate to the Activity list view, and click your new button—you should see the Excel file download automatically
Troubleshooting Tips
  • CORS Errors: If Dynamics can’t call your API, check your host’s CORS settings to allow your Dynamics instance URL (e.g., https://yourorg.crm.dynamics.com)
  • Authentication Issues: If your API needs secure access, add API key validation or integrate with Azure AD OAuth to accept Dynamics user tokens
  • FetchXml Flexibility: To let users export their current view’s data, modify the JavaScript to pull the view’s FetchXml and send it to your API instead of using the fixed FetchXml in your code

内容的提问来源于stack exchange,提问作者Mohd Nazish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:30:39