Another Way to Update Properties


If you want to update a Vault property and that property is mapped to a value within the file, you have a couple of options, and they both suck.  This post is to introduce a third, and non-sucky, option in Vault 2015 R2.  Again, I’ll be using the previously undocumented functions from Copy Design.

Sucky option 1 is to checkout and download the CAD file.  Next, use the appropriate CAD API to update the file on disk.  Lastly, check the file back in to Vault.  What makes this option so difficult is that you need to involve the CAD API.  It would be nice to do just everything from within the Vault API.

Sucky option 2 is to use IExplorerUtil.UpdateFileProperties in the Vault API.  On paper, this is a great function.  It loads up core pieces of Vault Explorer libraries and executes the Edit Properties command just as if a user had done it through the UI.  It even handles the checkout/checkin.  The problem is that it’s a bulky operation and prone to failure.  Vault Explorer simply wasn’t meant to be invoked from the API.  IExplorerUtil was always indented to be a temporary solution until something better came along.  And that something better is here….


The new option is to use the Copy Design features.  Similar to how you can ‘roll your own’ copy design, you can also run a property update without ever invoking a CAD API or downloading the file.  It’s a 4 step process:

Step 1: Check out the file
DocumentService.CheckoutFile(…)

This step reserves the file to you for editing.  It also gives you a download ticket, which you will need in the next 2 steps.  Although you are not actually downloading anything, the ticket is the currency that the FilestoreService uses.

Step 2: Read the property definitions from the file
FilestoreService.GetContentSourcePropertyDefinitions(…)

This step interrogates the binary file and pulls out the names properties that you may be able to edit.  Unfortunately, it doesn’t tell you the current values on those properties.  Also keep in mind that this is the property as it appears in the file, which may not be the same name that it appears in Vault.  In fact, it may not be mapped to a Vault property at all.

Step 3:  Copy the binary contents file
FilestoreService.CopyFile(…)

This step will create a new binary blob of data in the Vault filestore.  It also lets you update properties on that blob.  The ‘writeReqs’ parameter let’s you pass in new values for the properties you discovered in part 2.  Only properties you pass in are updated.  All others are left with their existing value. 
It’s possible that not all properties you supplied will get updated, so check the ‘writeResults’ out parameter for confirmation.

Step 4: Check-in the file
DocumentService.CheckinUploadedFile(…)

This steps ties the binary data in the filestore with actual records in the Vault database.  Without this step, you just have a blob of data floating in limbo.  Although you copied binary data, it won't be used for creating a new File Master like with copy design.  Instead, you are creating a new version of an existing file.  From the filestore’s point of view, there is no difference between the two.  Both are just blobs of binary data.


Sample Code

You didn’t think I would go through all this without providing any sample code, did you?  Not a chance.  I actually have an mini app that illustrates this workflow and the a simple Copy Design workflow from the previous post.  Includes C# and VB.NET source code. Enjoy.

Click here to download



Comments

8 responses to “Another Way to Update Properties”

  1. Hi Doug
    It is nice way to update fileproperties, but it is again only a half solution. I only want to put in the vault properties i have to change for an specific object and that’s it. I’ dont want to care about all the things around the object. In my opinion an API has to simplify all the complicated things behind the scene.
    regards Gerhard

  2. Could you explain the next step, how to fix the file references?
    In my example, I would like to copy both the model, and the drawing, that are associated with an item. So, using your code, I can copy both files, and promote the new file to an item. But, how do I link the new drawing to the new model file?
    Thanks for all your help,
    Shane

  3. So you basically want your own version of Copy Design. Have a look at this article: http://justonesandzeros.typepad.com/blog/2015/02/roll-your-own-copy-design.html
    In the last step, AddUploadedFile(..), is where you specify the references to any child files. You will need to look at the relationships of the original files and make sure to set things up the same way for the new files.
    At that point you should be good. Internal references are fixed up on download. So when you call AcquireFiles, the Vault framework will edit your local copy to point to the new file.

  4. Hi Doug,
    Great demo here, it helped me through most of a migration though I find myself stuck. I’m not as experienced with the Vault APIs as I would like to be so I think I might be missing a trick. Two questions:
    1) When going through the code above you handle properties that already exist on the file. I notice that there is an option for “CanCreate” and I imagine that if set to true it would create this property on the file. The problem being that I don’t know where to get the Moniker from for a property that exists in Vault SQL but not yet in the File. I found a previous article that talks about debugging and hard coding these values though I would much prefer a dynamic way of getting this information. I have an inkling that the file’s source API (Inventor in this case) might be the answer that I don’t want to hear. Is there a Vault API way to do this?
    2) The method you present here and the method I have been shown to implement is to check a file out, mod it’s properties then check the file back in. Assuming you allow bi-directional updating between mapped properties the method above (and previously DocumentService.UpdateFileProperties(…)) works, assuming that the property already exists on the File. What I was thinking is that it must be more straightforward to update the Vault SQL properties then sync them to the file, telling the Vault to create the properties if they don’t exist. If there are already good examples of this that I have been unable to find then I would greatly welcome links and references. On the contrary side there might be a good article somewhere that explains why this is not the case.
    Whatever the outcome might be, any and all help will be greatly appreciated.
    Jake

  5. Have a look at these articles if you haven’t already.
    For some background on how “Vault SQL” properties and file properties work: http://justonesandzeros.typepad.com/blog/2010/06/properties-in-vault-2011—part-2.html
    For sample code on finding the moniker:
    http://justonesandzeros.typepad.com/blog/2010/07/properties-in-vault-2011—part-4.html
    2) Are you talking about unmapped properties? Properties that just live in Vault and not the file? Yes, those are easier to update. You can just call DocumentService.UpdateFileProperties on the files. No need to download or copy the file. However, I think you still need to checkout/checkin the file.

  6. Hi Doug,
    Thanks for your answers. I looked through the posts that you linked with a clearer head and noticed that I was using the PropDef class rather than the PropDefInfo class which was the reason I could only get limited information compared with the examples in the post about Monikers.
    I tried to implement this with some success but I tripped up over the creation of a Vault property in a file that does not yet have the matching, mapped property (This was caused by a new property being added through further API development some years after the first release. New files always worked as required but old files needed the property adding in order to work). I found that I could not use the “CanCreate” variable to force the creation of the missing property to the point where I received an error from the server. I’m not sure what the error was, I only know that if I set CanCreate to true for any property that did not exist on the file then it would cause an exception.
    After all of this I started to think over your comments about using DocumentService.UpdateFileProperties(). The reason I was doing any of this was because of the removal of the version of UpdateFileProperties that was previously being used. Following this through further I realised that I had misunderstood the newer version that uses PropInstParamArray[] as a variable. Once I followed this through and tweaked my Vault property settings everything was working again.
    In conclusion its working. Thanks again for your help and for all of the outstanding blog posts.
    Jake

  7. Jake, did you end up having to check the file in and out to update the property values? I’ve found I can create and remove propdefs on dwgs without having to check in and check out, but it throws an error when Itrying to check the file back in. The strange thing is, if I stop debugging after it has checked the file out and updated the values, but BEFORE trying to check the file back in, the vault shows the file as checked out WITH the new values. .. I end up having to check the file back in with admin privileges. Any help is definitely appreciated. Vault Mechanical 2015 R2, by the way…

  8. Sorry, Professional. Not Mechanical…

Leave a Reply to NickCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading