Community
Vault Customization
Share your knowledge, ask questions, and explore popular Vault API, Data Standard, and VBA topics related to programming, creating add-ins, or working with the Vault API.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Handling Properties for Folders and Files

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
keone_martin
407 Views, 4 Replies

Handling Properties for Folders and Files

Greetings folks,

 

I'm a bit of a Vault newbie in general and have been getting into the SDK for building a Vault extension the last few weeks. I'm a pretty experienced coder but am struggling to get a few things done that I would have expected to be fairly simple and standard user flows.

 

Too long don't want to read:
I'm looking for a simple way to update Properties on Files and Folders that I am creating through my Vault Explorer Extension. Preferably before creation to avoid incrementing version numbers unnecessarily. I'd like to use C# as I've written my extension in that so far.

 

Some context:
At present we create Projects in Vault for the normal Vault like capacities.

We also track information in various other places relevant to these projects.

To prevent double handling we would like to build a Vault Explorer Extension to achieve the following:

Add an action menu to the Nav Selection Set for right clicks on folders.

On activation display a form for data input relevant to the project.

On form submission, generate a new Vault Project Folder (and call some APIs etc not relevant to the questions here).

Populate some Custom Properties on the Folder.

Optionally copy some files in from our templates folder (and update some properties on them as well).

 

I have currently gotten through all of the UI setup. On form submission I am generating a new Folder using the Data Standards numbering scheme. I am also successfully copying the template files into the Folder.

 

Now for the problems I am facing. For the template copying I am not sure I am doing it in the most efficient or "best practice" way. I am a bit surprised there isn't a method on the DocumentServices to the effect of "MakeDuplicateFile("path/to/file", "output/folder") like there is for the MoveFile. Here's what I ended up with:

        private FileIteration CopyTemplate(string inputFile, long outputFolderId, string outputFileName)
        {
            WebServices.File[] files = _connection.WebServiceManager.DocumentService.FindLatestFilesByPaths(new[] { inputFile });
            long fileMasterId = files[0].MasterId;
            ByteArray[] ticket = _connection.WebServiceManager.DocumentService.GetDownloadTicketsByMasterIds(new[] { fileMasterId });
            FileAssocParam[] fileAssocParams = new FileAssocParam[0];
            BOM bom = new BOM();
            System.IO.Stream fileStream = new MemoryStream(ticket[0].Bytes);
            IDictionary<long, Currency.Entities.Folder> projectFolder = _connection.FolderManager.GetFoldersByIds(new[] { outputFolderId });
            FileIteration newVersion = _connection.FileManager.AddFile(projectFolder[outputFolderId], outputFileName, "", DateTime.Now, fileAssocParams, bom, FileClassification.None, false, fileStream);
            return newVersion;

        }

 

Now for the crux of why I am here petitioning for your assistance in these dark times. I have just spent the better part of a business day looking to do the properties section of my use case, and am not having much luck.

 

I almost made it for the File properties using:

        private void UpdateFileProperties(FileIteration file, Dictionary<string, string> formData)
        {
            // Update the properties of the file
            WebServices.File existingFile = _documentService.GetFileById(file.EntityIterationId);
            PropDef[] atts = _propertyService.GetPropertyDefinitionsByEntityClassId("FILE");
            PropInstParam[] properties = new PropInstParam[0];
            foreach (PropDef att in atts)
            {
                if (formData.ContainsKey(att.DispName))
                {
                    PropInstParam property = new PropInstParam();
                    properties.Append(property);
                }
            }
            PropInstParamArray propsArray = new PropInstParamArray();
            propsArray.Items = properties;
            PropInstParamArray[] propInstParamArrays = new PropInstParamArray[] { propsArray };
            long[] fileIds = new long[] { existingFile.MasterId };
            _documentService.UpdateFileProperties(fileIds, propInstParamArrays);
        }

but got agonisingly close to the finish line before hitting the "File isn't checked out" error for the last call. I can go the effort of adding the checkout logic, although it seems to add complexity since the method call involves local paths and machines and I'd rather not have a local version of the file. It also means that each template copied in would be immediately set to iteration 2. I found the AddFileWithBehaviors method but that requires an input file to copy the properties from (and I'm not sure it wouldn't cause issues with random other behaviors but I could look into that). I could update the properties on the template before I duplicated it each time and then at least that file would be the one incrementing versions which isn't super relevant since it's just a template... but it again feels over engineered for something which feels like it should be common place.

 

As for the Folder properties I haven't even gotten that far. The UpdateFileProperties throws a file not found error when given a folder id (not surprisingly), and there are no other methods I can find that seem to be set for this.

 

I have investigated the DocumentService, DocumentServiceExtensions, PropertyService, and various others. I've also tried searching here and found a few references to VDS but I'd rather maintain the logic in the one application using the one language (I'm new to C# and would rather not have to delve into PowerShell at the same time unless I need to).

Any help much appreciated. I hope the war and peace version of my plight wasn't too gruelling to read.

Labels (1)
4 REPLIES 4
Message 2 of 5
Nick_Hall
in reply to: keone_martin

Hi

 

Two things immediately come to mind

  • Every time you make a change to a file in Vault, whether it's the file itself or a property attached to the file, it will result in a new version.
    If you really want the newly-copied file to be Version 1, the only way to do it is to a) make sure all the properties update File -> Vault or File <-> Vault, and b) set all the properties on the file before the initial check in

  • If you can live with the newly-copied file not being Version 1, then you just need to check out the file before updating the properties. Note that you don't have to download the file if you are only updating Vault properties - having the file checked out will be enough

Hope that helps

Nick

 

Message 3 of 5
keone_martin
in reply to: Nick_Hall

Thank you @Nick_Hall that is a great help to start. I'm not super familiar with the business side of Vault either so I wasn't sure how relevant an extra version number is but if increasing it to update the properties is the expected behaviour the I'll definitely just add in the checkout code for the update.

 

Do you have advice for me on the Folder section? Are Folders considered Files when it comes to the UpdateFileProperties method? If not is there another method that I'm missing in the SDK? 

 

It's also maybe worth noting for you and others that the properties aren't reliant on a two way binding with the file itself, they are purely metadata to be stored for external reference.

 

Thank you for the help so far. I hope your day is going well.

 

Regards,

Keone Martin

Message 4 of 5
Nick_Hall
in reply to: keone_martin

Hi @keone_martin

 

  • Are Folders considered Files when it comes to the UpdateFileProperties method?
    If not is there another method that I'm missing in the SDK?

    The method you are looking for is UpdateFolderProperties, but it's part of the DocumentServiceExtensions Class, not the DocumentService class

  • " the properties aren't reliant on a two way binding with the file itself, they are purely metadata to be stored for external reference."

    In that case, you have no alternative but to use UpdateFileProperties, and have an extra version

On the subject of versions, in my opinion a few extra versions don't matter, because it's the Revision that really matters. Others may disagree (butNick_Hall_0-1716782827509.png)

 

This is especially true if the underlying file doesn't change (as in the use case you describe), because it only costs you a few database entries - Vault does not make a copy of the file if it is the same as the previous version

 

Hopefully that will get you through the next stage with your project

Nick

Message 5 of 5
keone_martin
in reply to: Nick_Hall

Thanks Nick,

 

A touch embarrassed that I missed the Folder update method on the Extensions class.

 

I very much appreciate your assistance and have successfully implemented the things I was looking to do.

For anyone who may find my solutions helpful in the future:

Files:

       private void UpdateFileProperties(FileIteration file, Dictionary<string, string> formData)
       {
           // Update the properties of the file
           WebServices.File checkedOutFile = CheckoutFile(file.EntityIterationId);
           
           PropDef[] atts = _propertyService.GetPropertyDefinitionsByEntityClassId("FILE");
           List<PropInstParam> properties = new List<PropInstParam>();
           foreach (PropDef att in atts)
           {
               if (formData.ContainsKey(att.DispName))
               {
                   PropInstParam property = new PropInstParam();
                   property.PropDefId = att.Id;
                   property.Val = formData[att.DispName];
                   properties.Add(property);
               }
           }
           
           PropInstParamArray propsArray = new PropInstParamArray();
           propsArray.Items = properties.ToArray();
           PropInstParamArray[] propInstParamArrays = new PropInstParamArray[] { propsArray };
           long[] fileIds = new long[] { checkedOutFile.MasterId };
           _documentService.UpdateFileProperties(fileIds, propInstParamArrays);
         
       }

       private WebServices.File CheckoutFile (long fileId)
       {
           CheckoutFileOptions options = new CheckoutFileOptions(); 
           string machine = Environment.MachineName;
           string tempFolder = Path.GetTempPath();
           string comment = "";
           ByteArray downloadTicket = new ByteArray();
           WebServices.File file = _documentService.CheckoutFile(fileId, options, machine, tempFolder, comment, out downloadTicket);

           return file;
       }

Please note that this code doesn't check the file back in, as that was the desired state.

Folders:

private void UpdateFolderProperties(long folderId, Dictionary<string, string> formData)
{

    // Update the properties of the file
    
    PropDef[] atts = _propertyService.GetPropertyDefinitionsByEntityClassId("FLDR");
    List<PropInstParam> properties = new List<PropInstParam>();

    foreach (PropDef att in atts)
    {

        if (formData.ContainsKey(att.DispName))
        {
            PropInstParam property = new PropInstParam();
            property.PropDefId = att.Id;
            property.Val = formData[att.DispName];
            properties.Add(property);
        }
    }
    PropInstParamArray propsArray = new PropInstParamArray();
    propsArray.Items = properties.ToArray();
    PropInstParamArray[] propInstParamArrays = new PropInstParamArray[] { propsArray };
    long[] folderIds = new long[] { folderId };
    _documentServiceExtensions.UpdateFolderProperties(folderIds, propInstParamArrays );
}



Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report