I'm trying to create an API connected to Vault Professional 2023 that, when I change the state of an item, automatically updates the state of the underlying files, making their state match that of the item.
I created my API in Visual Studio (C#) using AI, but I keep getting errors related to LifecycleService
methods, even though these methods are documented in the vaultSDK.chm
file.
Does anyone know why this API is not working? Also, since I'm not very experienced, is there anything structurally missing or incorrect in my code?
Thanks in advance!
using Autodesk.Connectivity.Extensibility.Framework;
using Autodesk.Connectivity.WebServices;
using Autodesk.Connectivity.WebServicesTools;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
[assembly: ApiVersion("16.0")]
[assembly: ExtensionId("12345678-ABCD-1234-ABCD-12345678ABCD")]
public class FileStateInheritanceJob : IJobHandler
{
public bool CanProcess(string jobType)
{
return jobType == "UpdateFileState";
}
public void OnJobProcessing(IJob job)
{
try
{
using (WebServiceManager manager = new WebServiceManager(job.Connection))
{
ItemService itemService = manager.ItemService;
DocumentService docService = manager.DocumentService;
LifeCycleService lifecycleService = manager.LifeCycleService;
// Recupera i parametri del job
Dictionary<string, string> paramsDict = ConvertXmlToDictionary((string)job.Params);
long itemId = long.Parse(paramsDict["ItemId"]);
// Recupera l'articolo
Item[] items = itemService.GetItemsByIds(new long[] { itemId });
if (items == null || items.Length == 0)
throw new Exception("Articolo non trovato.");
Item item = items[0];
// Ottenere lo stato di ciclo di vita dell'item
LfCycState[] states = lifecycleService.GetLifeCycleStatesByIds(new long[] { item.LfCycStateId });
LfCycState itemState = states.FirstOrDefault();
if (itemState == null)
throw new Exception("Stato del ciclo di vita non trovato.");
string newState = itemState.Name;
// Recupera i file associati all'articolo
ItemFileAssoc[] fileAssocs = itemService.GetItemFileAssociationsByItemIds(new long[] { item.MasterId }, ItemFileLnkTypOpt.Primary);
if (fileAssocs == null || fileAssocs.Length == 0) return;
foreach (var fileAssoc in fileAssocs)
{
long fileId = fileAssoc.CldFileId;
Autodesk.Connectivity.WebServices.File file = docService.GetFileById(fileId);
if (file == null || file.FileLfCyc == null)
continue;
// Recupera lo stato attuale del file
LfCycState[] fileStates = lifecycleService.GetLifeCycleStatesByIds(new long[] { file.FileLfCyc.LfCycStateId });
LfCycState fileState = fileStates.FirstOrDefault();
if (fileState != null && fileState.Name == newState)
continue; // Se lo stato è già corretto, salta
// Ottieni il nuovo ID dello stato del ciclo di vita del file
long newStateId = GetNewStateId(lifecycleService, file.FileLfCyc.LfCycDefId, newState);
// Aggiorna lo stato del file usando il metodo corretto
lifecycleService.UpdateLifeCycleStateTransitionJobTypes(
new long[] { file.Id },
new long[] { GetTransitionIdForState(lifecycleService, file.FileLfCyc.LfCycDefId, newState) },
new string[] { "Ereditarietà automatica" },
new string[] { "Cambio di stato automatico" }
);
LogEvent($"Stato del file {file.Name} aggiornato a {newState}.");
}
}
}
catch (Exception ex)
{
LogEvent("Errore durante l'elaborazione del job: " + ex.Message);
throw;
}
}
private long GetTransitionIdForState(LifeCycleService lifecycleService, long lfCycDefId, string newState)
{
LfCycTrans[] transitions = lifecycleService.GetLifeCycleStateTransitionsByIds(new long[] { lfCycDefId });
foreach (LfCycTrans transition in transitions)
{
LfCycState[] states = lifecycleService.GetLifeCycleStatesByIds(new long[] { transition.ToId });
if (states.Any(state => state.Name == newState))
{
return transition.Id;
}
}
throw new Exception($"Transizione per lo stato '{newState}' non trovata.");
}
private Dictionary<string, string> ConvertXmlToDictionary(string xmlString)
{
var dict = new Dictionary<string, string>();
XDocument xml = XDocument.Parse(xmlString);
foreach (var element in xml.Root.Elements())
{
dict[element.Name.LocalName] = element.Value;
}
return dict;
}
private long GetNewStateId(LifeCycleService lifecycleService, long lifecycleDefId, string stateName)
{
LfCycState[] states = lifecycleService.GetLifeCycleStatesByIds(new long[] { lifecycleDefId });
foreach (LfCycState state in states)
{
if (state.Name == stateName)
{
return state.Id;
}
}
throw new Exception($"Stato '{stateName}' non trovato nel ciclo di vita.");
}
private void LogEvent(string message)
{
string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FileStateJobLog.txt");
System.IO.File.AppendAllText(logPath, DateTime.Now + " - " + message + Environment.NewLine);
}
}