Introduction
In modern application development, integrating with robust data platforms is essential for scalability and flexibility. Microsoft Dataverse (formerly known as Common Data Service) provides a secure and cloud-based storage option for your data, acting as the underlying data platform for Microsoft Power Platform and Dynamics 365 applications.
In this tutorial, we'll guide you through creating a CRUD (Create, Read, Update, Delete) Web API using a Dataverse entity in ASP.NET Web API. This step-by-step guide is designed for beginner programmers, offering detailed explanations and code samples.
Prerequisites
Before you begin, ensure you have the following:
- Visual Studio 2022 (Community Edition is sufficient)
- .NET 6 SDK or later
- An active Dataverse environment (available through a Power Apps trial)
- Basic knowledge of C# and .NET
- Azure Active Directory (Azure AD) access (for app registration)
- Microsoft.PowerPlatform.Dataverse.Client NuGet package
Table of Contents
- Setting Up the Development Environment
- Creating a Dataverse Entity
- Creating the ASP.NET Web API Project
- Connecting to Dataverse from the Web API
- Implementing CRUD Operations
- Testing the API
- Conclusion
1. Setting Up the Development Environment
Install Visual Studio 2022
- Download and install Visual Studio 2022 Community Edition from the official website.
- During installation, select the following workloads:
- ASP.NET and web development
- .NET desktop development
Install .NET 6 SDK
- Download and install the .NET 8 SDK from the .NET Downloads page.
Set Up a Dataverse Environment
- Sign up for a free Power Apps trial if you don't have an existing environment.
- Access the Power Apps portal at https://make.powerapps.com/.
2. Creating a Dataverse Entity
Access Dataverse in Power Apps
- Navigate to Dataverse > Tables in the left-hand menu.
Create a New Table (Entity)
-
Click on + New table.
-
Configure the new table:
-
Display Name:
Student
-
Plural Display Name:
Students
-
Primary Column:
Student Name
- Click Create.
-
Display Name:
Add Columns to the Table
Add the following columns to the Student
table:
-
Age
- Data type: Number (Whole Number)
-
Email
- Data type: Text
-
Enrollment Date
- Data type: Date and Time (Date Only)
Save the table after adding all columns.
3. Creating the ASP.NET Web API Project
Create a New Project
- Open Visual Studio 2022.
- Click on Create a new project.
- Select ASP.NET Core Web API.
- Click Next.
Configure the Project
-
Project Name:
DataverseWebApi
- Location: Choose your preferred directory.
- Click Next.
Set Additional Information
-
Framework:
.NET 8.0 (Long-term support)
- Authentication Type: None
- Enable OpenAPI support: Checked (for Swagger UI)
- Click Create.
4. Connecting to Dataverse from the Web API
To interact with Dataverse, we'll use the Microsoft.PowerPlatform.Dataverse.Client
NuGet package.
Install the NuGet Package
- Right-click on the project in Solution Explorer.
- Select Manage NuGet Packages.
- Go to the Browse tab, search for
Microsoft.PowerPlatform.Dataverse.Client
. - Install the latest stable version.
Register an Application in Azure AD
-
Go to the Azure Portal.
-
Navigate to Azure Active Directory > App registrations.
-
Click New registration.
-
Name:
DataverseWebApiApp
- Supported account types: Accounts in this organizational directory only
-
Redirect URI:
https://localhost
- Click Register.
-
Name:
-
Note down the Application (client) ID.
-
In Certificates & secrets, create a new client secret. Note it down.
Add Connection String to appsettings.json
Open appsettings.json and add your Dataverse connection string:
{
"ConnectionStrings": {
"Dataverse": "AuthType=ClientSecret;Url=https://yourorg.crm.dynamics.com;ClientId=your_client_id;ClientSecret=your_client_secret;LoginPrompt=Auto"
}
}
- Replace
https://yourorg.crm.dynamics.com
with your Dataverse organization URL. - Replace
your_client_id
andyour_client_secret
with the values from Azure AD.
Security Note: For production, use secure methods like Azure Key Vault to store secrets.
5. Implementing CRUD Operations
Create a Model for Student
Create a Models folder. Add a new class Student.cs:
using System;
namespace DataverseWebApi.Models
{
public class Student
{
public Guid Id { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
public string Email { get; set; }
public DateTime EnrollmentDate { get; set; }
}
}
Create a Service to Interact with Dataverse
Create a Services folder. Add a new class DataverseService.cs:
using Microsoft.PowerPlatform.Dataverse.Client;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DataverseWebApi.Models;
using Microsoft.Extensions.Configuration;
namespace DataverseWebApi.Services
{
public class DataverseService
{
private readonly ServiceClient _serviceClient;
public DataverseService(IConfiguration configuration)
{
var connectionString = configuration.GetConnectionString("Dataverse");
_serviceClient = new ServiceClient(connectionString);
}
public async Task<Guid> CreateStudentAsync(Student student)
{
var entity = new Entity("student"); // Replace with your entity logical name
entity["studentname"] = student.StudentName;
entity["age"] = student.Age;
entity["email"] = student.Email;
entity["enrollmentdate"] = student.EnrollmentDate;
return await Task.Run(() => _serviceClient.Create(entity));
}
public async Task<Student> GetStudentAsync(Guid id)
{
var columns = new ColumnSet("studentname", "age", "email", "enrollmentdate");
var entity = await Task.Run(() => _serviceClient.Retrieve("student", id, columns));
if (entity == null) return null;
return new Student
{
Id = entity.Id,
StudentName = entity.GetAttributeValue<string>("studentname"),
Age = entity.GetAttributeValue<int>("age"),
Email = entity.GetAttributeValue<string>("email"),
EnrollmentDate = entity.GetAttributeValue<DateTime>("enrollmentdate")
};
}
public async Task UpdateStudentAsync(Student student)
{
var entity = new Entity("student", student.Id);
entity["studentname"] = student.StudentName;
entity["age"] = student.Age;
entity["email"] = student.Email;
entity["enrollmentdate"] = student.EnrollmentDate;
await Task.Run(() => _serviceClient.Update(entity));
}
public async Task DeleteStudentAsync(Guid id)
{
await Task.Run(() => _serviceClient.Delete("student", id));
}
public async Task<List<Student>> GetStudentsAsync()
{
var query = new QueryExpression("student")
{
ColumnSet = new ColumnSet("studentname", "age", "email", "enrollmentdate")
};
var entities = await Task.Run(() => _serviceClient.RetrieveMultiple(query));
var students = new List<Student>();
foreach (var entity in entities.Entities)
{
students.Add(new Student
{
Id = entity.Id,
StudentName = entity.GetAttributeValue<string>("studentname"),
Age = entity.GetAttributeValue<int>("age"),
Email = entity.GetAttributeValue<string>("email"),
EnrollmentDate = entity.GetAttributeValue<DateTime>("enrollmentdate")
});
}
return students;
}
}
}
Explanation:
-
Entity Logical Names: Replace
"student"
,"studentname"
, etc., with your actual entity logical names from Dataverse. - ServiceClient: Manages the connection to Dataverse.
Register the Service in Dependency Injection
In Program.cs, add:
builder.Services.AddSingleton<DataverseService>();
Create the StudentsController
Create a new controller StudentsController.cs in the Controllers folder:
using DataverseWebApi.Models;
using DataverseWebApi.Services;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace DataverseWebApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class StudentsController : ControllerBase
{
private readonly DataverseService _dataverseService;
public StudentsController(DataverseService dataverseService)
{
_dataverseService = dataverseService;
}
// GET: api/Students
[HttpGet]
public async Task<ActionResult<IEnumerable<Student>>> GetStudents()
{
var students = await _dataverseService.GetStudentsAsync();
return Ok(students);
}
// GET: api/Students/{id}
[HttpGet("{id}")]
public async Task<ActionResult<Student>> GetStudent(Guid id)
{
var student = await _dataverseService.GetStudentAsync(id);
if (student == null)
{
return NotFound();
}
return Ok(student);
}
// POST: api/Students
[HttpPost]
public async Task<ActionResult<Student>> CreateStudent(Student student)
{
var id = await _dataverseService.CreateStudentAsync(student);
student.Id = id;
return CreatedAtAction(nameof(GetStudent), new { id = student.Id }, student);
}
// PUT: api/Students/{id}
[HttpPut("{id}")]
public async Task<IActionResult> UpdateStudent(Guid id, Student student)
{
if (id != student.Id)
{
return BadRequest();
}
await _dataverseService.UpdateStudentAsync(student);
return NoContent();
}
// DELETE: api/Students/{id}
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteStudent(Guid id)
{
await _dataverseService.DeleteStudentAsync(id);
return NoContent();
}
}
}
Explanation:
- Each action method corresponds to a CRUD operation.
-
Dependency Injection: The controller uses
DataverseService
injected via constructor.
6. Testing the API
Run the Application
Press F5 in Visual Studio to run the application. The Swagger UI should open automatically.
Using Swagger UI
Create a New Student
-
Expand POST /api/Students.
-
Click Try it out.
-
Enter the following JSON in the Request body:
{ "studentName": "Alice Smith", "age": 22, "email": "alice.smith@example.com", "enrollmentDate": "2023-09-01" }
-
Click Execute.
-
You should receive a 201 Created response with the student details.
Retrieve All Students
- Expand GET /api/Students.
- Click Try it out and then Execute.
- The response should list all students in Dataverse.
Update a Student
- Copy the
Id
of the student you want to update. - Expand PUT /api/Students/{id}.
- Click Try it out.
- Enter the
Id
in the id parameter. - Modify the JSON in the Request body as needed.
- Click Execute.
Delete a Student
- Expand DELETE /api/Students/{id}.
- Click Try it out.
- Enter the
Id
of the student to delete. - Click Execute.
Verify in Dataverse
- Return to the Power Apps portal.
- Open the Students table to see the changes reflected.
Conclusion
You've successfully built a CRUD Web API using a Dataverse entity in ASP.NET Web API! This API can be extended or integrated into other applications, providing a powerful way to manage data stored in Dataverse.
Key Takeaways
- Dataverse Integration: Leveraging Dataverse allows for scalable and secure data management.
-
ServiceClient Usage: The
Microsoft.PowerPlatform.Dataverse.Client
simplifies interactions with Dataverse. - ASP.NET Web API: Building APIs with ASP.NET Core is efficient and aligns with modern web development practices.
Next Steps
- Security Enhancements: Implement secure storage for connection strings and secrets (e.g., using Azure Key Vault).
- Error Handling: Add robust error handling and logging mechanisms.
- Authentication: Secure your API endpoints with authentication and authorization.
Additional Resources
- Microsoft Dataverse Documentation
- https://github.com/icpmtech/CRUDWebAPIDataverseEntities
- ASP.NET Core Web API Documentation
- Microsoft.PowerPlatform.Dataverse.Client NuGet Package
Looking to optimize your software skills? Visit askpedromartins.com for expert advice and solutions tailored to your development needs.