0

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?

6
  • 1
    Try checking to see if properties.AfterProperties["ContentTypeId"].ToString(); is present. For some reason, that field may not be available. Commented Mar 15, 2013 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
    Commented Mar 15, 2013 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. Commented Mar 16, 2013 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
    Commented Mar 18, 2013 at 18:50
  • I'm glad you were able to get it working. Commented Mar 18, 2013 at 19:26

5 Answers 5

1

Try

properties.ListItem.ContentType

Or try what Quinn said:

string ctid = properties.AfterProperties["ContentTypeId"].ToString();
properties.List.ContentTypes[ctid];
1
  • 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
    Commented Jul 3, 2013 at 18:27
0

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];
0

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.

0

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.

0

Steve and Quinn's responses are correct with a little modification as highlighted in bold.

string ctid = properties.AfterProperties["ContentTypeId"].ToString();
properties.List.ContentTypes[**new SPContentTypeId(ctid)**];

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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