I have had a chance to look into this again now, and found that indeed it is possible to access and change properties in ItemAdding, if you are doing it through the "AfterProperties" hash table of the event, and not through the list item.
Some things to note:
During ItemAdding, there is no SPListItem object to refer to. It is null in the event properties, because to get an SPListItem a record for the item should be in the database, and during ItemAdding nothing has been written to the database yet.
After ItemAdding, the item is added to the database. When it is added, the values from the AfterProperties are applied to it. If you try to add a property to that hashtable that doesnt exist in the list definition, the user will get an error that the field isn't installed correctly. You may encounter this if you don't use the internal name of the field when you set the AfterProperties.
The moral of the story - Use the AfterProperties in ItemAdding, and when you use it to get or set a field, make sure you use the field's internal name.
That said, my argument with Sahil (see below in the original post) remains - you cannot use the SPListItem, because one cannot exist. His sample code modifies the item that was added before the current item, and not the current one.
Here is a sample code that modifies one of the fields in the ItemAdding event. In this example we have a links list, with a custom column called "Tool Tip" (internal name is "Tool_0x0020_Tip") and we want to set it automatically to the title of the link the user picked:
public override void ItemAdding(SPItemEventProperties properties)
string toolTipFieldInternalName = "";
using (SPWeb web = properties.OpenWeb())
toolTipFieldInternalName = web.Lists[properties.ListId].Fields[TOOL_TIP_FIELD_NAME].InternalName;
string urlVal = properties.AfterProperties["URL"].ToString();
SPFieldUrlValue val = new SPFieldUrlValue(urlVal);
string desc = val.Description;
properties.AfterProperties[toolTipFieldInternalName] = desc;
I have been trying to create an event handler that checks the item's properties before it is saved. This is supposed to be easy in MOSS - just create an event handler, override the "ItemAdding" event and check the properties of the list item. right?
Apperantly, the SPItemEventProperties object that is received in the ItemAdding event is totaly useless! The "ListItem" is null, the ListItemID is null, the AfterProperties and the BeforeProperties are both empty so basically we have no idea what the user typed - we have no way to control it!
Searching the internet I found that Sahil wrote a terrific article on creating an event handler (with really good funny writing and good guidlines) in which he tried to implement a workaround to the problem.
Unfortunately, I tested his code and it seems something is missing. I think he meant to use the ItemAdded event or something (or maybe not, since his scenario demands using the ItemAdding event).
Basically he is trying to get the item from the list by getting the last item int the list. But he didnt notice that the item doesnt exist yet, so his code is quering an existing item instead of the new one about to be added - he is always checking the last item in the list, but not the one the event is triggered for. So to sumarrize - I found no way currently to get the list item details before it is added to the list (then you can use the "ItemAdded" event). I have contacted Microsoft and waiting for their reply.
If you are using Sahil's article (which is quite good except for the above), look out for embedding the list's URL in the code. Sahil probably meant to write about it, but he focused on the demo.
The more elegant way to get to the list is:
Shail's original code SPList SahilSurvey = properties.OpenWeb().GetList("http://homepc/Lists/Sahil");
My proposed change: SPList SahilSurvey = properties.OpenWeb().Lists[properties.ListId];
You will notice that in my solution you dont have to hard code the list URL, and that way you make the event handler generic- able to handle all lists instead of just the one under "http://homepc/Lists/Sahil".