Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an item in Tridion 2011 using Core Service

Tags:

tridion

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;
    }
}
like image 450
robrtc Avatar asked Mar 07 '12 10:03

robrtc


1 Answers

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?

like image 196
Andrey Marchuk Avatar answered Nov 05 '22 20:11

Andrey Marchuk