This posting is all about source code. Here you will find useful code snippets for dealing with properties.
How to get the list of legal values for a property definition
If you have a property definition that contains a list of legal values, you need to get the PropDefInfo object to read that list of values. GetPropertyDefinitionInfosByEntityClassId is the only way to get this object, but it seems that you need to be an administrator to call this function. There is an undocumented trick to get this information with normal permissions. Pass in null to the 'propertyDefIds' parameter. It will return all PropDefInfo objects and it will remove the admin requirement.
|
// C# // Get all file PropDefInfo objects |
|
' VB.NET ' Get all file PropDefInfo objects
|
How to look up a system property
For system properties it's OK to hardcode the system name since the name will be the same in all vaults and languages. FindPropertyDefinitionsBySystemNames is the API function to use and it's pretty straightforward in how it works. The trick is finding the system name. In the properties dialog, you can customize the columns to show the system name of each property definition.
Note that the systems names are nice and simple. However any UDPs that you create will have a randomly generated GUID attached to them. So the system name is not a good way to look up UDPs.
How to look up a mapped property
Sometimes all you care about is the file property and you want to see the vault PropDef that has a read mapping to that file property. Hardcoding the system name isn't helpful since UDP names and property mappings may change from vault to vault.
What you need is to find the moniker for the file property and use that file to find the vault PropDef. Note: there may be no mappings or multiple mappings to the file property.
|
// the moniker for the "Company" property in an Inventor file. foreach (PropDefInfo propDef in propDefs) { bool matchFound = false; if (propDef.EntClassCtntSrcPropCfgArray == null) continue; foreach (EntClassCtntSrcPropCfg contentSource in propDef.EntClassCtntSrcPropCfgArray) { if (contentSource.EntClassId != "FILE" || contentSource.CtntSrcPropDefArray == null) continue; for (int i = 0; i < contentSource.CtntSrcPropDefArray.Length; i++) { if (contentSource.CtntSrcPropDefArray[i].Moniker == moniker && contentSource.MapDirectionArray[i] == MappingDirection.Read) { mappedToContent.Add(propDef); matchFound = true; break; } } if (matchFound) break; } }
|
|
Dim mappedToContent As New List(Of PropDefInfo)() If propDef.EntClassCtntSrcPropCfgArray Is Nothing Then For Each contentSource As EntClassCtntSrcPropCfg In propDef.EntClassCtntSrcPropCfgArray For i As Integer = 0 To contentSource.CtntSrcPropDefArray.Length – 1
|
How to find the moniker
This is a bit tricky. I don't recommend trying to figure out the syntax we use. Instead I recommend the following:
- Create a new UDP and map it to the property within the file.
- Write a code snippet that gets the PropDefInfo object for your UDP.
- In the debugger expand out the EntClassCtntSrcPropCfgArray of the PropDefInfo object.
- You should be able to find the mapping along with the moniker value.
- Copy the moniker value into your code.
How to find the CtntSrc object for a file
CtntSrc is the object representing a content source provider. Each file will have 1 and only 1 provider. You can locate the correct object using the Provider system property on a file.
|
IEnumerable<PropDefInfo> results = propDefInfos.Where(prop => prop.PropDef.SysName == "Provider"); PropInst[] values = propSvc.GetProperties("FILE", new long[] { file.Id }, new long[] { providerProp.PropDef.Id }); ServerCfg config = adminSvc.GetServerConfiguration(); IEnumerable<CtntSrc> providers = config.CtntSrcArray.Where(source => source.DispName == providerName); |
|
Dim values As PropInst() = propSvc.GetProperties("FILE", New Long() {file.Id}, New Long() {providerProp.PropDef.Id}) Dim config As ServerCfg = adminSvc.GetServerConfiguration() Dim providers As IEnumerable(Of CtntSrc) = From source In config.CtntSrcArray _
|
Note: "IFilter" is the system name to the "All Files" provider. This should be used if the provider value is blank or there is no match to any other provider.
How to update a UDP value on a file
There are two ways of doing this. The correct way depends on if the UDP is mapped or not.
The unmapped UDP is the simple case, you just call UpdateFileProperties. If the UDP has a read mapping, UpdateFileProperties will not help you. The reason is because when the file is checked in, the file's internal value will overwrite the UDP value you just set. The correct thing to do is to update the property inside the local file before checking it back in to Vault. This means that you need to use the appropriate CAD API to set the file data. Once the file is checked in, the Vault server will update the mapped UDP value
|
// TODO: checkout file if (isMapped) // TODO: checkin file |
How to tell if a UDP is mapped
Here is code to determine if a property has a read mapping or not. Since each provider sets its own mappings, you need the CtntSrc object from the earlier section.
|
IEnumerable<PropDefInfo> results = propDefInfos.Where(prop => prop.PropDef.Id == propDefId); bool isMapped = false; for (int i=0; i < contentSource.CtntSrcPropDefArray.Length; i++) |
|
Dim results As IEnumerable(Of PropDefInfo) = From prop In propDefInfos _ Dim isMapped As Boolean = False For i As Integer = 0 To contentSource.CtntSrcPropDefArray.Length – 1 If contentSource.CtntSrcPropDefArray(i).CtntSrcId = provider.Id AndAlso contentSource.MapDirectionArray(i) = MappingDirection.Read Then |
Conclusion
That's all I have planned for my series on properties. If more questions/issues come in, I may decide to add a part 5.
Thanks to everyone for all the great feedback.
Coming in July: A series of articles on connected workgroups (aka. Replication)

Leave a Reply