InstanceService.UpdateInstance
Reference
DateTime UpdateInstance(Instance instance, DateTime? lastModified)
Use UpdateInstance to modify an existing Type instance by updating its attributes and other properties. This API performs validation, executes triggers, and ensures data consistency while returning the updated modification timestamp.
Parameters
instance: The instance contract containing updated data. Must include a valid Id for the instance to update.Id: Required - The unique identifier of the instance to update.Name: Optional - Updated instance name.Attributes: Optional - Array of attributes to update with new values.ParentAttributes: Optional - Array of parent attribute relationships to update.Geofence: Optional - Geofence data if the instance supports location-based features.
lastModified: Optional timestamp for optimistic concurrency control. If provided, ensures the instance hasn't been modified since this time.
Returns
DateTime: The updated modification timestamp of the instance after successful update.
Error Handling & Caveats
- If the instance does not exist or the user lacks permission, an AccessDeniedException is thrown.
- If the instance has been modified since
lastModifiedtimestamp, a ConcurrencyException is thrown. - If attribute validation fails (e.g., required attributes missing, invalid data types), a ValidationException is thrown.
- If business rule triggers fail, the update is blocked and error details are returned.
- If the instance is locked by another process, an InstanceLockException is thrown.
- Updates are performed atomically - if any part fails, the entire update is rolled back.
- Geofence updates trigger location-based events and validations if configured.
- Parent attribute updates may affect related instances and their relationships.
Usage
try {
// First fetch the existing instance
var instance = InstanceService.GetInstance(existingInstanceId);
// Update the name
instance.Name = "Updated Task Name";
// Update specific attributes
var statusAttr = instance.Attributes.FirstOrDefault(a => a.Name == "Status");
if (statusAttr != null)
{
statusAttr.TextValue = "In Progress";
}
else
{
// Add new attribute if it doesn't exist
var attrs = instance.Attributes.ToList();
attrs.Add(new Attribute {
Name = "Status",
Type = AttributeType.Text,
TextValue = "In Progress"
});
instance.Attributes = attrs.ToArray();
}
var updatedTimestamp = InstanceService.UpdateInstance(instance, instance.Modified);
Console.WriteLine($"Instance updated successfully at {updatedTimestamp}");
} catch (AccessDeniedException ex) {
// Handle permission errors
} catch (ConcurrencyException ex) {
// Handle concurrent modification conflicts
} catch (ValidationException ex) {
// Handle validation errors
foreach (var error in ex.ValidationErrors) {
Console.WriteLine($"Validation error: {error.Message}");
}
}
Example: Updating Date Attributes
try {
var requestDate = contract.Attributes.FirstOrDefault(a => a.Name == "RequestedDate");
var approvedDate = contract.Attributes.FirstOrDefault(a => a.Name == "ApprovedDate");
// Update existing attributes or add new ones
SetDateTimeAttributeToNow(contract, requestDate, "RequestedDate");
SetDateTimeAttributeToNow(contract, approvedDate, "ApprovedDate");
InstanceService.UpdateInstance(contract, contract.Modified);
Console.WriteLine("Contract dates updated successfully");
} catch (Exception ex) {
Console.WriteLine($"Error updating contract dates: {ex.Message}");
}
private void SetDateTimeAttributeToNow(Instance instance, Attribute dateAttribute, string attributeName)
{
if (dateAttribute != null)
{
dateAttribute.DateValue = DateTime.UtcNow;
}
else
{
var attrs = instance.Attributes.ToList();
attrs.Add(new Attribute
{
Name = attributeName,
Type = AttributeType.DateTime,
DateValue = DateTime.UtcNow
});
instance.Attributes = attrs.ToArray();
}
}
Example: Batch Attribute Updates
try {
// Fetch the existing project instance
var instance = InstanceService.GetInstance(projectInstanceId);
// Update multiple attributes
var statusAttr = instance.Attributes.FirstOrDefault(a => a.Name == "Status");
if (statusAttr != null) statusAttr.TextValue = "Active";
var progressAttr = instance.Attributes.FirstOrDefault(a => a.Name == "Progress");
if (progressAttr != null) progressAttr.NumericValue = 75;
var reviewedAttr = instance.Attributes.FirstOrDefault(a => a.Name == "LastReviewed");
if (reviewedAttr != null) reviewedAttr.DateValue = DateTime.UtcNow;
var reviewerAttr = instance.Attributes.FirstOrDefault(a => a.Name == "ReviewedBy");
if (reviewerAttr != null) reviewerAttr.ReferenceValue = currentUserId;
var updatedTimestamp = InstanceService.UpdateInstance(instance, instance.Modified);
Console.WriteLine($"Project attributes updated successfully");
} catch (ConcurrencyException ex) {
// Instance was modified by another user - refresh and retry
Console.WriteLine("Instance was modified by another user. Please refresh and try again.");
} catch (ValidationException ex) {
// Display specific validation errors
Console.WriteLine("Validation failed:");
foreach (var error in ex.ValidationErrors) {
Console.WriteLine($"- {error.AttributeName}: {error.Message}");
}
}
Example: Copying and Updating Related Instance Attributes
try {
var sourceInstance = InstanceService.GetInstance(sourceInstanceId);
var targetInstance = InstanceService.GetInstance(targetInstanceId);
var newTargetAttributes = new List<Attribute>();
foreach (var sourceAttr in sourceInstance.Attributes)
{
Attribute newAttribute = null;
switch (sourceAttr.Name)
{
case "Category":
newAttribute = new Attribute {
Name = "DerivedCategory",
Type = AttributeType.Text,
TextValue = sourceAttr.TextValue
};
break;
case "Priority":
newAttribute = new Attribute {
Name = "InheritedPriority",
Type = AttributeType.Text,
TextValue = sourceAttr.TextValue
};
break;
default:
break;
}
if (newAttribute != null)
newTargetAttributes.Add(newAttribute);
}
if (newTargetAttributes.Any())
{
targetInstance.Attributes = newTargetAttributes.ToArray();
InstanceService.UpdateInstance(targetInstance, targetInstance.Modified);
Console.WriteLine("Attributes copied and updated successfully");
}
} catch (Exception ex) {
Console.WriteLine($"Error copying attributes: {ex.Message}");
}
Troubleshooting
- If ConcurrencyException occurs frequently, implement retry logic with fresh lastModified timestamps.
- If ValidationException occurs, check that all required attributes are provided with valid data types and values.
- If InstanceLockException occurs, wait and retry the operation as the instance may be temporarily locked.
- For performance issues with large attribute sets, consider updating only changed attributes rather than the entire instance.
- Always use the correct AttributeType when setting attribute values (Text, Numeric, DateTime, Reference, etc.).
- When adding new attributes, ensure they exist in the instance type schema and are properly typed.
- For date/time attributes, use DateTime.UtcNow for consistency across time zones.
- If triggers are blocking updates, review business rules and ensure all required conditions are met.
- Use
instance.Modifiedfor optimistic concurrency control to prevent overwriting concurrent changes. - When copying attributes between instances, handle type conversions and name mappings appropriately.