Skip to main content

PreGet Trigger

  • PreGet Trigger programs are executed before an instance is retrieved from the system.
  • Used to enforce access control, perform pre-fetch validations, or modify retrieval behavior.
  • Can prevent access to an instance by returning a failure result.

Coding Guidelines

  • Implement the async interface for all new logic:
public interface IPreGetTriggerProgram
{
ProgramResult Run(Instance instance);
}

public interface IPreGetTriggerProgramAsync
{
Task<ProgramResult> RunAsync(Instance instance);
}
  • The trigger receives the Instance object to be accessed.
  • Return a ProgramResult indicating success or failure, with error messages as needed.
    • If IsSuccess is true, the trigger execution is considered successful and instance retrieval proceeds.
    • If IsSuccess is false, the trigger is considered failed, instance retrieval is blocked, and the API response will include the error messages from the Errors array for the end user.
    • Always provide clear, actionable error messages in Errors when access is denied or validation fails.

Example Program

Below is an example of a PreGet trigger program that implements access validation logic. This program checks whether the current user is authorized to access the requested instance by comparing project names:

  • It retrieves the current user's profile and fetches the AllowedProjects reference attribute (representing project names the user can access).
  • It fetches the Project reference attribute from the instance being accessed (representing the project name associated with the instance).
  • It compares the allowed project names assigned to the user with the project name on the instance.
  • If there is no match, access is denied and a user-friendly error message is returned.
  • If a match is found, access is allowed.
public class PreGetTriggerProgram : IPreGetTriggerProgramAsync
{
public IInstanceService InstanceService { get; set; }
public IUserService UserService { get; set; }
// ... other services ...

public async Task<ProgramResult> RunAsync(Instance instance)
{
try
{
var user = UserService.GetUserLite();
if (user == null)
return new ProgramResult { IsSuccess = false, Errors = new[] { "We couldn't find your user profile. Please contact your administrator for access." } };

var userProfileAttributes = InstanceService.GetInstance(user.TypeInstanceId, new[] { "AllowedProjects" }).Attributes;
var allowedProjects = userProfileAttributes.FirstOrDefault(a => a.Name == "AllowedProjects");
if (allowedProjects?.ReferenceValues == null)
return new ProgramResult { IsSuccess = false, Errors = new[] { "You do not have any projects assigned to your profile. Please check with your administrator." } };

var projectOnInstance = instance.Attributes.FirstOrDefault(a => a.Name == "Project");
if (projectOnInstance?.ReferenceValues == null)
return new ProgramResult { IsSuccess = false, Errors = new[] { "This instance is not linked to any project. Please contact support if you believe this is an error." } };

var projectNamesOnInstance = projectOnInstance.ReferenceValues.Select(r => r.Name).ToList();
if (!allowedProjects.ReferenceValues.Any(r => projectNamesOnInstance.Contains(r.Name)))
return new ProgramResult { IsSuccess = false, Errors = new[] { "You do not have permission to access this project. If you need access, please request it from your administrator." } };

return new ProgramResult { IsSuccess = true };
}
catch (Exception ex)
{
return new ProgramResult { IsSuccess = false, Errors = new[] { "An unexpected error occurred while checking your access. Please try again later or contact support if the problem persists." } };
}
}
}

Best Practices

  • Use async methods for all service/API calls.

  • Return clear, user-friendly error messages in ProgramResult.Errors.

    • Note: Error messages returned from PreGet triggers are displayed directly in the API response to the end user. Write messages that are easy to understand and actionable for users.
  • Avoid heavy logic in the sync interface.

  • Do not perform update or any heavy operation in this trigger. Performing updates or resource-intensive logic may significantly slow down instance retrieval for the end user.

Typical Use Cases

  • Enforcing access control based on user profile or roles before allowing instance retrieval.
  • Validating that the user is authorized to access specific reference attributes on the instance.
  • Restricting access to sensitive data based on business rules or compliance requirements.
  • Blocking retrieval if required attributes or relationships are missing or invalid.
  • Validating or modifying instance and attribute values (including all attribute types: basic, custom attributes: text, picklist, numeric, boolean, expression, user, reference, etc.) based on business logic before access.

Anti-patterns

  • Do not perform post-retrieval actions here.
  • Do not use for logging or notifications after access.