Hello Aspose Support Team,
I have encountered a significant issue when creating hierarchical OutlineCode definitions programmatically and saving the project to MPP format. While the hierarchy is correctly preserved in XML format, it is completely lost (all ParentValueId reset to 0) when saving to MPP and reloading.
Problem Summary
When creating OutlineCodeDefinition and OutlineValue programmatically and saving to MPP:
- ParentValueId relationships are lost after save/reload (Project → Save(Mpp) → new Project(file)).
- In MS Project UI, dropdown values are visible for OutlineCode field, but selecting a value does not populate task cell.
Expected
- Parent/child hierarchy in OutlineCodeDefinition.Values is preserved in .mpp.
- Selecting a value from the OutlineCode dropdown should set the field value for task.
Actual
- After MPP save+reload, all values become root (ParentValueId = 0).
- In MS Project, values are shown but cannot be applied to task field.
Product / Version
- Aspose.Tasks for .NET 26.1 (also reproduced on 25.12)
- .NET 8
- MS Project Desktop (opens generated .mpp)
Observed Output after reloading .mpp
- ValueId=1, ParentValueId=0, Value=PARENT
- ValueId=2, ParentValueId=0, Value=CHILD ← expected ParentValueId=1
Additional Note
In generated XML (SaveFileFormat.Xml), hierarchy is represented correctly (ParentValueID=1 for child), but .mpp behavior is incorrect
Minimal Repro Code (C#)
using System;
using System.Linq;
using Aspose.Tasks;
using Aspose.Tasks.Saving;
class Repro
{
static void Main()
{
var project = new Project();
var def = new OutlineCodeDefinition
{
FieldId = ExtendedAttributeTask.OutlineCode10.ToString("D"),
FieldName = "MiniOC10",
Alias = "MiniOC10",
OnlyTableValuesAllowed = true,
ShowIndent = true
};
def.Masks.Add(new OutlineMask
{
Level = 1,
Type = MaskType.Characters,
Separator = ".",
Length = 0
});
def.Masks.Add(new OutlineMask
{
Level = 2,
Type = MaskType.Characters,
Separator = ".",
Length = 0
});
var parent = new OutlineValue
{
ValueId = 1,
Value = "PARENT",
Type = OutlineValueType.Text
};
var child = new OutlineValue
{
ValueId = 2,
Value = "CHILD",
Type = OutlineValueType.Text,
ParentValueId = 1
};
def.Values.Add(parent);
def.Values.Add(child);
project.OutlineCodes.Add(def);
// Optional task with selection
var t = project.RootTask.Children.Add("Task 1");
t.OutlineCodes.Add(new OutlineCode
{
FieldId = def.FieldId,
ValueId = 2
});
var mppPath = @"C:\Temp\outline-mini.mpp";
var xmlPath = @"C:\Temp\outline-mini.xml";
project.Save(mppPath, SaveFileFormat.Mpp);
project.Save(xmlPath, SaveFileFormat.Xml);
var reloaded = new Project(mppPath);
var defReloaded = reloaded.OutlineCodes.FirstOrDefault(d => d.FieldId == def.FieldId);
Console.WriteLine($"Values: {defReloaded?.Values.Count}");
if (defReloaded != null)
{
foreach (var v in defReloaded.Values.OrderBy(v => v.ValueId))
{
Console.WriteLine($"ValueId={v.ValueId}, ParentValueId={v.ParentValueId}, Value={v.Value}");
}
}
}
}