This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

[COM API] Mixed result with creating Vault structure through code

Working on something fun, but having mixed results: can't get a perfect result with creating structure through code, using AddObjectTypeAdmin, AddPropertyDefAdmin, AddObjectClassAdmin.

Expected: creating an OT "Log", PD "LogMessage", a CL "Log" through code and aliases for each.
Result: an OT Log, PD LogMessage, but TWO "Log" classes (with sequential ids), where the first has become a "builtin" class (when I try to delete it from my local vault)!
See screenshot

It's a bit of a hit or miss with examples lacking for AddObjectTypeAdmin, AddPropertyDefAdmin, AddObjectClassAdmin

This is my code. What am I missing that causes two Log classes to be created?

var logObjectTypeID = vault.ObjectTypeOperations.GetObjectTypeIDByAlias("OT.Log");
var logClassID = vault.ClassOperations.GetObjectClassIDByAlias("CL.Log");
var logMessagePropDefID = vault.PropertyDefOperations.GetPropertyDefIDByAlias("PD.LogMessage");


// Add Log ObjectType if it doesn't exist
if (logObjectTypeID == -1)
{
ObjType objType = new ObjType()
{
NameSingular = "Log",
NamePlural = "Logs",
AllowAdding = false,
AllowedAsGroupingLevel = false,
RealObjectType = true,
CanHaveFiles = false,
External = false,
ShowCreationCommandInTaskPane = false,
Hierarchical = false,
HasOwnerType = false,
OwnerType = 0,
Translatable = false
};

var objTypeAdmin = new ObjTypeAdmin()
{
ObjectType = objType,
SemanticAliases = new SemanticAliases() { Value = "OT.Log" }
};

var newObjTypeAdmin = vault.ObjectTypeOperations.AddObjectTypeAdmin(objTypeAdmin);
logObjectTypeID = newObjTypeAdmin.ObjectType.ID;
}

// Add LogMessage propertyDef if it doesn't exist
if (logMessagePropDefID == -1)
{
var propDef = new PropertyDef
{
Name = structureConfig.LogMessagePropDefName,
DataType = MFDataType.MFDatatypeMultiLineText,
ContentType = MFContentType.MFContentTypeGeneric,
ObjectType = logObjectTypeID, // Either ID of the newly created ObjectType or the found-by-alias ObjectType
BasedOnValueList = false,
AllObjectTypes = false,
Predefined = false,
ObjectsSearchableByThisProperty = false,
HistoryVersionsSearchableByThisProperty = false,
AllowedAsGroupingLevel = false,
SortAscending = true,
FormattingType = MFFormattingType.MFFormattingTypeNone,
AutomaticValueType = MFAutomaticValueType.MFAutomaticValueTypeNone,
ValidationType = MFValidationType.MFValidationTypeNone,
UpdateType = MFUpdateType.MFUpdateTypeNormal,
AccessControlList = new AccessControlList(),
};

var propDefAdmin = new PropertyDefAdmin()
{
PropertyDef = propDef,
SemanticAliases = new SemanticAliases() { Value = "PD.LogMessage" }
};

var newPropertyDefAdmin = vault.PropertyDefOperations.AddPropertyDefAdmin(propDefAdmin);
logMessagePropDefID = newPropertyDefAdmin.PropertyDef.ID;
}


// Add Class if it doesn't exist
if (logClassID == -1)
{
var associatedNamePropDef = new AssociatedPropertyDef
{
PropertyDef = 0, // NameOrTitle
Required = true
};

var associatedLogMessagePropDef = new AssociatedPropertyDef
{
PropertyDef = logMessagePropDefID,
Required = false
};

var associatedPropDefs = new AssociatedPropertyDefs();
associatedPropDefs.Add(-1, associatedNamePropDef);
associatedPropDefs.Add(-1, associatedLogMessagePropDef);

var objectClassAdmin = new ObjectClassAdmin
{
Name = structureConfig.LogClassName,
ObjectType = logObjectTypeID,
NamePropertyDef = 0, // NameOrTitle PropertyDef
AssociatedPropertyDefs = associatedPropDefs,
ForceWorkflow = false,

SemanticAliases = new SemanticAliases() { Value = "CL.Log" }
};

var newClassAdmin = vault.ClassOperations.AddObjectClassAdmin(objectClassAdmin);
logClassID = newClassAdmin.ID;
}
  • When you create the object type it will automatically create various mandatory vault structural elements to support it.  These include, for example, a default class, the default property definition (used for relationships) and the "Owner" property definition.

    If you want to assign aliases and the like to those items then you need to create the object type first, load the automatically-created items, then alter them and re-save.

    Regards,

    Craig.

  • Thank you, Craig, that sounds somewhat logical.

    So, I create the OT and that one creates some other things as well, like the class? And I have to find that class and update it?

    I remember I saw another post somewhere / M-Files platform training reference stating that updating alias would need to reassign some other fields as well otherwise saving would fail?

  • Hi Victor,

    Yep: create the object type, then load the (automatically-created) class and alter it as needed.

    I believe the issue you're referring to is that the ObjectClassAdmin's "associated properties" collection is basically empty (noted on the link I just gave).  This actually shouldn't matter to you as it's an empty class and you are then going to populate it correctly, but is important to note if you make subsequent changes to an existing class.

    Regards,

    Craig.

  • Thx Craig! Got it working with vault.ClassOperations.GetObjectClassesAdmin() and UpdateObjectClassAdmin()