In Tridion 2011 I want to use the Core Service equivalent of UpdateXml to create new Tridion objects in a generic way. I intend to create new Components, Pages and later on Folders and Structure Groups. It works quite well using UpdateXml but I am having a problem with casting the RepositoryLocalObject
(or another generic-type object) to a ComponentData
object with the Core Service. My Core Service code is much longer (and growing by the second).
Error message when I try to access on object-type specific property:
Error 9 'Tridion.ContentManager.CoreService.Client.RepositoryLocalObjectData' does not contain a definition for 'Content' and no extension method 'Content' accepting a first argument of type 'Tridion.ContentManager.CoreService.Client.RepositoryLocalObjectData'
Would a possible solution be to create an extension method?
Tridion TOM API:
Function CreateNewItemCopy(organizationalItemUri, itemType, title, xml,
directory, filename)
Dim newItem : set newItem = tdse.GetNewObject(itemType, organizationalItemUri)
newItem.UpdateXml(xml)
newItem.Title = title
if(itemType = 64) then ' page
newItem.FileName = filename
elseif(itemType = 4) then ' sg
newItem.Directory = directory
end if
newItem.save(true)
CreateNewItemCopy = newItem.id
set newItem = nothing
End Function
Tridion 2011 Core Service
*Updated Code Based on Excellent Answer Below
private ItemType GetTridionItemType(RepositoryLocalObjectData source)
{
string itemType = source.GetType().Name;
switch (itemType)
{
case "ComponentData":
return ItemType.Component;
case "PageData":
return ItemType.Page;
}
return ItemType.UnknownByClient;
}
private string CreateNewItemCopy(string title, RepositoryLocalObjectData source,
string filename)
{
ItemType tridionItemType = GetTridionItemType(source);
string orgItemUri = source.LocationInfo.OrganizationalItem.IdRef;
var newItem = client.Copy(source.Id, orgItemUri, true, new ReadOptions());
newItem.Title = title;
if (tridionItemType == ItemType.Page)
{
PageData pageData = newItem as PageData;
pageData.FileName = filename;
client.Update(pageData, new ReadOptions());
}
else
{
client.Update(newItem, new ReadOptions());
}
return newItem.Id;
}
*Original Code
private string CreateNewItemCopy(string title, RepositoryLocalObjectData source,
string filename)
{
string newItemUri = "";
try
{
ItemType tridionItemType = GetTridionItemType(source.Id);
string orgItemUri = source.LocationInfo.OrganizationalItem.IdRef;
if (tridionItemType == ItemType.Component)
{
ComponentData sourceComp = source as ComponentData;
ComponentData newComponent = client.GetDefaultData(tridionItemType,
orgItemUri) as ComponentData;
newComponent.Title = title;
newComponent.Metadata = source.Metadata;
// ** Only Component has .Content and SchemaRef
newComponent.Content = sourceComp.Content;
newComponent.Schema.IdRef = sourceComp.Schema.IdRef;
client.Create(newComponent, null);
newItemUri = newComponent.Id;
}
else if (tridionItemType == ItemType.Page)
{
PageData sourcePage = source as PageData;
PageData newPage = client.GetDefaultData(tridionItemType,
orgItemUri) as PageData;
newPage.Title = title;
newPage.Metadata = source.Metadata;
// ** Only Page has .Filename
newPage.FileName = filename;
client.Create(newPage, null);
newItemUri = newPage.Id;
}
else // I would really like to handle all things here - but have problems with
// item-specific mandatory properties, such as Schema, Filename, and Dir
{
var newGenericTridionItem = client.GetDefaultData(tridionItemType,
orgItemUri) as RepositoryLocalObjectData;
newGenericTridionItem.Title = title;
newGenericTridionItem.Metadata = source.Metadata;
//if(GetTridionItemType(newGenericTridionItem.Id) == ItemType.Page)
// newGenericTridionItem.filename;
client.Create(newGenericTridionItem, null);
newItemUri = newGenericTridionItem.Id;
}
}
catch (Exception ex)
{
throw;
}
return newItemUri;
}
private ItemType GetTridionItemType(string uri)
{
const int itemTypeComp = 16;
const int itemTypePage = 64;
const int itemTypeSG = 4;
const int itemTypeFolder = 2;
int itemTypeInt = GetTridionItemTypeId(uri);
switch (itemTypeInt)
{
case itemTypeComp:
return ItemType.Component;
break;
case itemTypePage:
return ItemType.Page;
break;
case itemTypeSG:
return ItemType.StructureGroup;
break;
case itemTypeFolder:
return ItemType.Folder;
break;
}
return ItemType.UnknownByClient;
}
private int GetTridionItemTypeId(string uri)
{
const int itemTypeComp = 16;
string[] uriParts = uri.Split('-');
if (uriParts.Length == 2) // comp, tcm:9-1234
{
return itemTypeComp;
}
else // other, tcm:9-456-64 for a page...
{
int itemTypeId = Int32.Parse(uriParts[2]);
return itemTypeId;
}
}
I have slightly adjusted your code and now it's working:
private string CreateNewItemCopy(string title, RepositoryLocalObjectData source, string filename)
{
string newItemUri = "";
try
{
ItemType tridionItemType = GetTridionItemType(source);
string orgItemUri = source.LocationInfo.OrganizationalItem.IdRef;
if (tridionItemType == ItemType.Component)
{
ComponentData sourceComp = source as ComponentData;
ComponentData newComponent = client.GetDefaultData(tridionItemType, orgItemUri) as ComponentData;
newComponent.Title = title;
newComponent.Metadata = source.Metadata;
// ** Only Component has .Content and SchemaRef
newComponent.Content = sourceComp.Content;
newComponent.Schema.IdRef = sourceComp.Schema.IdRef;
newItemUri = client.Create(newComponent, new ReadOptions()).Id;
}
else if (tridionItemType == ItemType.Page)
{
PageData sourcePage = source as PageData;
PageData newPage = client.GetDefaultData(tridionItemType, orgItemUri) as PageData;
newPage.Title = title;
newPage.Metadata = source.Metadata;
// ** Only Page has .Filename
newPage.FileName = filename;
newItemUri = client.Create(newPage, new ReadOptions()).Id;
}
else //I would really like to handle all things here - but have problems with item-specific mandatory properties, such as Schema, Filename, and Dir
{
var newGenericTridionItem = client.GetDefaultData(tridionItemType, orgItemUri) as RepositoryLocalObjectData;
newGenericTridionItem.Title = title;
newGenericTridionItem.Metadata = source.Metadata;
//if(GetTridionItemType(newGenericTridionItem.Id) == ItemType.Page)
// newGenericTridionItem.filename;
newItemUri = client.Create(newGenericTridionItem, new ReadOptions()).Id;
}
}
catch (Exception ex)
{
throw;
}
return newItemUri;
}
private ItemType GetTridionItemType(RepositoryLocalObjectData source)
{
string itemType = source.GetType().Name;
switch (itemType)
{
case "ComponentData":
return ItemType.Component;
case "PageData":
return ItemType.Page;
}
return ItemType.UnknownByClient;
}
But I still don't understand why do you want to do it this way and not use simple Copy method?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With