Implementing Operations in Bloqs
Operations in Bloqs are non-CRUD actions that can be executed within the system. Unlike standard Create, Read, Update, Delete actions, an operation represents a custom task or workflow you want to run.
Operations have an input entity that is sent to the API.
They can only be implemented on the API side.
The UI can trigger operations via a dedicated page.
Declaring an Operation in the Model
To add an operation, first declare its input class and register the operation in your app model.
.AddEntityClass<SendMailInput>()
.AddOperation(new Operation()
{
Id = AppConstants.Operations.SendMail,
Name = AppConstants.Operations.SendMailName,
})Input Entity Class
using Bloqs.App.Engine.Entities;
namespace Templates.SampleApp.Models.Operations;
public class SendMailInput : Entity
{
public required string MailAddress { get; set; }
public required string Message { get; set; }
}This entity defines the input required for the operation — in this case, an email address and a message body.
Implementing the Operation in the API
On the API side, you implement the operation by creating an Operation Command Handler.
using System.Net;
using System.Net.Mail;
using Bloqs.Api.Engine.DataAccess;
using Bloqs.App.Engine.Commands;
using Bloqs.App.Engine.Commands.Operation;
using Templates.SampleApp.Models;
using Templates.SampleApp.Models.Data;
using Templates.SampleApp.Models.Operations;
namespace Templates.SampleApp.Api.Commands.Operations;
[OperationCommandHandler(AppConstants.Operations.SendMailName)]
public class SendMail(IDataServiceCreator dataServiceCreator)
: ICommandHandler<OperationCommand, OperationCommandResult>
{
private const string SmtpUser = "tomv@noost.nl";
private const string SmtpPassword = "<insert gmail pwd>"; // Use the 16-character App Password
private const string SmtpHost = "smtp.gmail.com";
private const int SmtpPort = 587;
public async Task<OperationCommandResult> HandleAsync(
OperationCommand command,
CancellationToken cancellationToken = default
)
{
try
{
var dataService = dataServiceCreator.GetDataService<Activity>(
DataServiceCreatorArgs.FromCommand<Activity>(command)
);
var input =
command.InputEntity as SendMailInput
?? throw new Exception("Invalid input entity for SendMail operation");
var activity = await dataService.GetAsync(input.ActivityId);
var fromEmail = SmtpUser;
var toEmail = input.MailAddress;
var subject = "Email from Sample App: " + activity.Name;
var body = input.Message;
var mail = new MailMessage(fromEmail, toEmail, subject, body);
var smtp = new SmtpClient(SmtpHost, SmtpPort)
{
Credentials = new NetworkCredential(SmtpUser, SmtpPassword),
EnableSsl = true,
};
smtp.Send(mail);
Console.WriteLine("Email sent successfully.");
return OperationCommandResult.CreateSuccess(null);
}
catch (Exception ex)
{
Console.WriteLine($"Error sending email: {ex.Message}");
return OperationCommandResult.CreateFailure();
}
}
}This handler takes the SendMailInput object and performs the actual email sending logic.
Last updated