Second Life of a Hungarian SharePoint Geek

December 12, 2009

A duplicate name "MyPage" was found when creating content type derived from Page

Filed under: Content types, Reflection, SharePoint — Tags: , , — Peter Holpar @ 02:32

Recently I’ve got a task that seemed to be a routine job at first. I had to extend an existing publishing site with some new content types and publishing layouts. The content types should have been derived from the Page content type.

Everything was working as excepted while I the first few content type was created. When I was about to create the next content type, I received a warning that:

A duplicate name "MyPage" was found

It was not the general red validation message that informs you about that a content type with the same name already exists, but a warning message displayed on a separate page of its own.

Hmm. Interesting. I might have been created that already earlier? A quick check on the site content types showed that there is no existing content type with that name, and I was not able to get that content type from code either.

I’ve looked for possible reasons on the web, but found no matching result for my case. There was no parent or child web on the site, so it was not possible to have a conflict with one of the content types defined on another web level.

My investigation showed, that the situation is even worse, than seemed to be at the first sight. When I was to create a new content type derived from Page, I’ve got the same result regardless the name of the content type, of course, having different name in the error message. When I’ve tried to create a new content type with the very same name but deriving from other parent content type, it was created without error.

I’ve experienced the same when tried to create content type from code.

  1. SPContentTypeCollection contentTypes = web.ContentTypes;
  2. SPContentType contentType = new SPContentType(contentTypes["Page"], contentTypes, "MyPage");
  3. contentTypes.Add(contentType);

The exception was thrown on the last line, when adding the new content type to the collection. So I’ve started Reflector to see the condition when the exception should be thrown. And that is where I‘ve found the strangest thing.

There is a call in SPContentTypeCollection.Add() method to the internal method SPContentTypeCollection.Exists(). This method is called from Add having the first parameter the actual content type to check for existence, second parameter true, and the third parameter is of type SPContentType again, but this time it it an out parameter and contains the matching content type if it exists. The method returns a bool value indicating the result of the operation, true means that the content type already exists, false means it does not.

So I decided to include this check into my code just for fun, and to see, what the problem might be, what content type I will get from the out parameter.

Since the Exists method is private, calling that requires some Reflection tricks, but if you are a bit familiar with that kind of hacks, it is rather simple in this case. All we have to do is to get the type of SPContentTypeCollection, get a MethodInfo that describes the Exists method, then create the parameter array for call, and invoke the method, as shown in the code below.

Don’t forget to reference System.Reflection from your code!

  1. SPContentTypeCollection contentTypes = web.ContentTypes;
  2. SPContentType contentType = new SPContentType(contentTypes["Page"], contentTypes, "MyPage");
  3.  
  4. // a few extra lines to hack
  5. SPContentType contentTypeOut = null;
  6. Type typeSPContentTypeCollection = contentTypes.GetType();
  7. MethodInfo miExists = typeSPContentTypeCollection.GetMethod("Exists", BindingFlags.NonPublic | BindingFlags.Instance);
  8. object[] methodParms = new object[] { contentType, true, contentTypeOut};
  9. try
  10. {
  11.     // result should be false and methodParams[2] should be null
  12.     Object result = miExists.Invoke(contentTypes, methodParms);
  13. }
  14. catch (Exception ex)
  15. {
  16.     Console.WriteLine(ex);
  17. }
  18. // hack finished
  19.  
  20. contentTypes.Add(contentType);

I’ve tried to debug my code step by step to see what happens, and what a surprise, the Exists method returned false, and the methodParams[2] remained null after invocation. Both of these means there is no matching content type found. I stepped forward in code debugging, and this time the content type was added without exception.

I’ve double checked that on the user interface, but the new content type was really there. It had the description of the Page parent content type, but it is due to the fact it was created from code and we have not set the value of the Description property.

After this trick, I was able to create new content types from the user interface too, but only for a limited time, since a few tries later it gave me the original exception again, so the trick had to be repeated. This time the first invocation of the Exists method returned true, and the methodParams[2] was not null, but an SPContentType instance. I’ve set the next statement to be the first line of the hack again, re-run the check, and this second time returned the expected result, and the new content type was added to the collection. I assume it was the result of a mistake during the debugging, while I had the debugger active in the background and context was not able to refresh.

Since this second time of applying the trick there is no issue with deriving new content types from Page.

There is no happy end or moral of the story, as I really don’t know why it all happened, but I think it might be useful for somebody who may have time to take the investigation further.

Advertisements

1 Comment »

  1. […] Second Life of a Hungarian SharePoint Geek If your sword is too short, take one step forward « A duplicate name "MyPage" was found when creating content type derived from Page […]

    Pingback by Checking the existence of a content type « Second Life of a Hungarian SharePoint Geek — December 12, 2009 @ 02:38


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: