armaSANEA


Hello! I'm trying to understand how content types work and what are its limitations. I need to have the possibility to change the content type of an item depending on certain conditions, and can't figure out how to do it!!

The closest I tried to come up with is this:

if (changeContentTypeRequired)

{

newFile.Item["Content Type"] = baseFolder.ContentTypeOrder[2];

newFile.Item.Update();

}

How do I change the content type of an item from code




Re: Custom Content types issue

MKeeper


Instead of accessing the Content Type using an index, you can use the "SPListItem.ContentType" property (shown here in MSDN)

You then need to allocate the value as an SPContentType object.

I'm assuming your "newFile" object is an SPFile which has been uploaded to a document library of some kind

(is this code an event handler by chance )

So...

Code Snippet

// get the List Item for the new SPFile object

SPListItem newItem = newFile.Item;

// using the list item's parent List, get the content type that

// I want to allocate from the List's Content Types collection

SPContentType cType = newItem.List.ContentTypes["My Content Type"];

// allocate that content type to the List Item

newItem.ContentType = cType;

// save the changes

newItem.Update();

regards

MKeeper






Re: Custom Content types issue

MKeeper

Also .. try looking at this blog article:

http://suguk.org/blogs/tomp/archive/2006/09/28/Adding_SPListItems.aspx







Re: Custom Content types issue

armaSANEA

First of all: Yes, the newFile object is a new SPFile that has been added to the folder.

Thank you for the answer! And for the link also. But I am quite confused on how you used this property:

Code Snippet
newItem.ContentType = cType;

The SPListItem.ContentType property is read only....

And I've tried this:

Code Snippet

SPListItem newItem = newFile.Item;

// using the list item's parent List, get the content type that

// I want to allocate from the List's Content Types collection

SPContentType cType = newItem.ParentList.ContentTypes["Excel file content type"];

// allocate that content type to the List Item

//newItem["ContentType"] = cType;

newFile.Item["ContentTypeId"] = cType.Id;

// save the changes

newFile.Item.Update();

I get the content type that I want - except it does not update the file info.. What am I doing wrong






Re: Custom Content types issue

MKeeper

Ooops .. sorry .. you are quite right. ContentType is readonly! Well done on the ContentTypeId property.

That should work though.

Just to make sure, apply the changes to the "newItem" object instead of the "newFile.Item" property.

so...

Code Snippet

SPListItem newItem = newFile.Item;

// using the list item's parent List, get the content type that

// I want to allocate from the List's Content Types collection

SPContentType cType = newItem.ParentList.ContentTypes["Excel file content type"];

// allocate that content type to the List Item

newItem["ContentTypeId"] = cType.Id;

// save the changes

newItem.Update();






Re: Custom Content types issue

armaSANEA

First of all thanks for your quick answers.. And no, the code is not in an event handler Smile

...this is horrible! I spent like 2 hours just to realize that a behavior was caused just by the WSS cache...

I can't seem to get this to neither way: neither through newItem["ContentTypeId"] = cType.Id; nor through newFile.Item["ContentTypeId"] = cType.Id;

I have this block now:

Code Snippet

public File AddFile( string filename )

{

byte[] bytecontents = new byte[0];

SPFile newFile = baseFolder.Files.Add( filename, bytecontents );

if (IsExcelFile(filename))

{

SPListItem newItem = newFile.Item;

// using the list item's parent List, get the content type that

// I want to allocate from the List's Content Types collection

SPContentType cType = newItem.ParentList.ContentTypes["Excel file content type"];

// allocate that content type to the List Item

newItem["ContentType"] = cType;

newItem["ContentTypeId"] = cType.Id;

newFile.Item["ContentType"] = cType;

newFile.Item["ContentTypeId"] = cType.Id;

// save the changes

newFile.Item.Update();

newItem.Update();

return new ExcelFile(newFile.Item);

}

return (File)SWBItemFactory.GetItem( newFile.Item );

}

and it DOES NOT work..

I must be really missing something.. HEEELP...






Re: Custom Content types issue

armaSANEA

Finally, I've got it!

The point was that I used several instances of the SPListItem, all of which pointed to the same file. After I updated the newItem (note that the update was on a separate object), the newFile.Item remained the same - and after the newFile.CheckIn() the info was back to that before the update.

I've also found a way to do it from the event handlers:

public override void ItemAdding( SPItemEventProperties properties )

{

if (File.IsExcelFileName(properties.AfterUrl))

{

try

{

SPWeb site = properties.OpenWeb();

SPList list = site.Lists[properties.ListId];

properties.AfterProperties["Content Type ID"] = list.ContentTypes["Excel file content type"];

}

catch (Exception exc)

{

Debug.WriteLine(exc.Message);

}

}

base.ItemAdding(properties);

}

Thanks MKeeper! You were right after all. Please note how I spelled AfterProperties["Content Type ID"] (with spaces.. not sure if they work without them).