Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I have a library that allows multiple folder content types. I am grouping the folders by content type but I don't want the group heading to say Content Type: whatever. Instead, I created a hidden column Study Type and I have an ItemAdding event receiver set this field when an item is created. This works fine.

Now it occurred to me that the client may want to edit the folder and my event receiver must still set the proper fields to new values. Easy, I thought. I would just add an ItemUpdating event to my receiver have it execute the same code and all done. But this doesn't work. Below is my code.

    public override void ItemAdding(SPItemEventProperties properties)
   {
       base.ItemAdding(properties);

       execute(properties);

   }

   public override void ItemUpdating(SPItemEventProperties properties)
   {
       base.ItemUpdating(properties);
       execute(properties);
   }

   public void execute(SPItemEventProperties properties)
   {
       base.EventFiringEnabled = false;

       SPList objlist = properties.List;
       System.Diagnostics.Trace.WriteLine("list " + objlist);
       string contentTypeName;
       SPContentType contentType;
       //initiolise(properties);

       if (objlist.Title == "In-House Studies" || objlist.Title == "CRO Studies" || objlist.Title == "Studies by Collaborators")
       {
           string titleInternalName = objlist.Fields["Study Type"].InternalName;
           string inVivoInVitro = objlist.Fields["In-Vivo/In-Vitro Type"].InternalName;
           string temp;
           try
           {
               contentTypeName = properties.AfterProperties["ContentType"].ToString();
               contentType = objlist.ContentTypes[contentTypeName];

               try
               {
                   if (contentType.Name == "In-Vitro Experiment")
                   {
                       properties.AfterProperties[titleInternalName] = "A.In-Vitro Experiment";
                       temp = objlist.Fields["In-Vitro Type"].InternalName;
                       properties.AfterProperties[inVivoInVitro] = properties.AfterProperties[temp];
                   }
                   else if (contentType.Name == "In-Vivo Study")
                   {
                       properties.AfterProperties[titleInternalName] = "B.In-Vivo Study";
                       temp = objlist.Fields["In-Vivo Type"].InternalName;
                       properties.AfterProperties[inVivoInVitro] = properties.AfterProperties[temp];
                   }
                   else if (contentType.Name == "CRO Study")
                   {
                       properties.AfterProperties[titleInternalName] = "A.CRO Study";
                   }
                   else if (contentType.Name == "Generic Folder")
                   {
                       properties.AfterProperties[titleInternalName] = "C.Generic";
                   }
                   else
                   {
                       properties.AfterProperties[titleInternalName] = "D.Document";
                   }

               }
               catch (Exception)
               {
                   properties.AfterProperties[titleInternalName] = "D.Document";
               }
           }
           catch (NullReferenceException)
           {
               properties.AfterProperties[titleInternalName] = "D.Document";
           }
       }

       base.EventFiringEnabled = true;
   }

Now my understanding is the AfterProperties contain the new values for the item in an ItemUpdating event receiver, however

    contentTypeName = properties.AfterProperties["ContentType"].ToString();

fails with a null reference exception. Why doesn't my code work with an ItemUpdating event receiver?

share|improve this question
1  
Try checking to see if properties.AfterProperties["ContentTypeId"].ToString(); is present. For some reason, that field may not be available. –  Quinn Johns Mar 15 '13 at 23:13
    
I am not sure I understand what you mean by present. Does "ContentType" get renamed in ItemUpdating event vs ItemAdding event? –  Eugene Mar 15 '13 at 23:43
    
Well, for some reason the ContentType field may not be available in ItemUpdating. However, I am suggesting for you to check the ContentTypeID field, as you may be able to use that. –  Quinn Johns Mar 16 '13 at 20:28
    
ContentTypeId exists but then propoerties.List.ContentTyes[crid] returns null. Anywyas I changed my event receiver to a synchronous ItemAdded and ItemUpdated so I can use properties.listItem and now everything works fine –  Eugene Mar 18 '13 at 18:50
    
I'm glad you were able to get it working. –  Quinn Johns Mar 18 '13 at 19:26
show 1 more comment

4 Answers

Try

properties.ListItem.ContentType

Or try what Quinn said:

string ctid = properties.AfterProperties["ContentTypeId"].ToString();
properties.List.ContentTypes[ctid];
share|improve this answer
    
properties.ListItem.ContentType gets the "Before" value, basically. Also, just putting the ctid in as a string tends to get me errors. I'm thinking there's something going on where maybe the ctid needs to be surrounded by {}'s before it will work? –  Matt Jul 3 '13 at 18:27
add comment

Thanks Steve, I guess I'll put my response as an answer, deviated from your response to my suggestion.

string ctid = properties.AfterProperties["ContentTypeId"].ToString();
properties.List.ContentTypes[ctid];
share|improve this answer
add comment

Check the intername of the column you are trying to get the data from. if you have changed the name of the column after creating the list, then try with the old name.

Use 'Title' if you have changed it.

share|improve this answer
add comment

Here's what I ended up doing to get a solution:

string beforecType = properties.BeforeProperties["ContentTypeId"].ToString()
    , aftercType = properties.AfterProperties["ContentTypeId"].ToString()
    , beforeCTypeName = null
    , afterCTypeName = null
    , baseCTypeName = mappingHandler.ActiveFields.SharepointContentTypeName;

foreach (SPContentType ct in properties.List.ContentTypes)
{
    // Contains is OK because there doesn't seem to be a way to break it this way, at least not without much much larger ID numbers
    if (beforecType != null && (ct.Id.ToString() == beforecType || ct.Id.ToString().Contains(beforecType)))
    {
        beforeCTypeName = ct.Name;
    }
    if (ct.Id.ToString() == aftercType || ct.Id.ToString().Contains(aftercType))
    {
        afterCTypeName = ct.Name;
    }
}

It's not as pretty as I'd like and potentially inefficient if you have just a TON of content types, but it works and it's still within ItemUpdating instead of one of the other events.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.