I'm having trouble getting the DateTime from a DateTimeField of an attached part I dynamically created and attached to a content type in a migration.
The structure is like this:
CourseDate (ContentType)
ProductPart (attached part from other project)
CourseDatePart (attached part)
TimeSpanPart (attached part from "dynamically" created part)
I'm trying to pull the StartDateTime and EndDateTime, which are DateTimeField, out of the TimeSpanPart. However the DateTime property is always 1/1/0001
Here's the code I'm using to pull the values. Everything else works except for the TimeSpanPart.
private EditCourseViewModel BuildEditorViewModel(CoursePart part)
{
var courseDates = _contentManager.Query<CourseDatePart, CourseDatePartRecord>().Where(x => x.CourseId == part.Id)
.List<CourseDatePart>()
.Select(x =>
new CourseDateViewModel
{
Id = x.Id,
StartDate = ((dynamic) x.ContentItem).TimeSpanPart.StartDateTime.DateTime,
EndDate = ((dynamic) x.ContentItem).TimeSpanPart.EndDateTime.DateTime,
Sku = ((dynamic) x.ContentItem).ProductPart.Sku,
IsDigital = ((dynamic) x.ContentItem).ProductPart.IsDigital,
Inventory = x.Inventory
}
);
When I inspect the value of x.Record.ContentItemRecord.Data, I can see that the data I want is there:
<Data><TimeSpanPart><StartDateTime>2013-09-02T06:20:00.0000000</StartDateTime><EndDateTime>2013-09-21T00:05:00.0000000</EndDateTime></TimeSpanPart></Data>
Here's the relevant parts of the migration:
ContentDefinitionManager.AlterPartDefinition("TimeSpanPart", part=>part
.Attachable()
.WithField("StartDateTime", f=>f.OfType("DateTimeField").WithDisplayName("Start Date Time"))
.WithField("EndDateTime", f=>f.OfType("DateTimeField").WithDisplayName("End Date Time"))
);
ContentDefinitionManager.AlterTypeDefinition("CourseDate", type=>type
.WithPart(typeof(CourseDatePart).Name)
.WithPart("TimeSpanPart")
.WithPart(typeof(ProductPart).Name)
);
Edit:
I dug a bit deeper into the Orchard InfosetStorageProvider class where it manages the storage for Fields. In the BindStorage method, it's passing the Data XML element to the Get method. But instead of passing infosetPart.Infoset.Element (which has the data I want shown above), it's passing infosetPart.ContentItem.VersionRecord because it's not null; it's an empty XML element instead: <Data />
return new SimpleFieldStorage(
(name, valueType) => Get(infosetPart.ContentItem.VersionRecord == null ? infosetPart.Infoset.Element : infosetPart.VersionInfoset.Element, partName, fieldName, name),
(name, valueType, value) => Set(infosetPart.ContentItem.VersionRecord == null ? infosetPart.Infoset.Element : infosetPart.VersionInfoset.Element, partName, fieldName, name, value));
}
How do I get it to correctly populate data into infosetPart.ContentItem.VersionRecord? Is this a bug in Orchard in that it's passing an empty xml <Data /> element instead of null so that it will instead pass infosetPart.Infoset.Element to the Get method, or am I doing something wrong? I have no idea what the difference is between infosetPart.ContentItem.VersionRecord and infosetPart.Infoset.Element.