Wednesday, September 27, 2006

Synchronous Add List event (ItemAdding) will not give access to item properties

UPDATE:

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;

        }

Original post: (was posted during Beta2) Ok - here is an update to my "Bad news - synchronous list events bug (or missing feature)" post from August:

I reported this as a bug to Microsoft, and got a response that they "cant repro this on a newer build - please check on TR".
So I waited for TR, and checked again - no change! The properties of the new list item are simply not accessible.
I reported this to MS, and this time gave a full code sample so that they will be able to repro exactly what I was trying to do.
The answer came back that this is by design!

Microsoft has no plans of giving us developers access to list item properties in the itemadding event. All you will know is that an item is being added. You will notice that the SDK was also updated to show a sample code that checks the number of items in the list and shows a user an error if there are 150 items in the list. But checking the new item's properties can only be done in the "itemadded" event.

By the way, this means that Sahil's example does have the bug I pointed out - during itemadding, the item is not yet added to the list and is not available through list.Items[list.Items.Count-1].

People- I think this is big enough that we should gang up on Microsoft and clamor for them to give us the ability to check properties of list items. Write comments here if you agree and we will build us a petition!

Sunday, September 24, 2006

Trouble with Beta2TR

Oh boy, its been a bad day for me, and its not even 15:00! Last week my sharepoint shared services started misbehaving (luckily, only after a major presentation I had) and today I just couldnt run searches any more, and the user profile database was down.

Going into the shared services administration screen and then clicking "search settings" would give me an error that the search service is offline or the index is being moved, and trying to go into the profile administration would tell me the SQL server database is unreachable.
The event log kept saying that my user account (lets call him spsadmin) failed to logon: "Login failed for user 'DOMAIN\spsadmin'. [CLIENT: ]"
which is very strange since that account is a machine admin, and a SQL admin and DBO for all databases.

isnt that cool?

What havent I tried?
I tried changing the accounts, the passwords, the services..I even tried restarting the server (who knows...).
Finally, I am trying now to reinstall sharepoint.
What I am worried about is installing sharepoint beta2 and then installing TR, on a machine with office beta2tr. I hope no conflicts arise.
Wish me luck!

Wednesday, September 20, 2006

Free web part, as promised! - User profile Checker

As I promised a couple of days ago, I have published a new webpart for download, complete with source code.

The web part checks the user's profile for properties that are marked as "required" and if a user didnt fill in one of them, he is prompted to fill it in:

You can also choose to have the user prompted by a message box, or just automatically redirect him!


Here is the download:
As an answer to the comments I will explain some more:

The web part checks the properties that are not disabled, that are user editable or are administrator editable and are required.
The property may be mapped to active directory,

Monday, September 18, 2006

The cursed Site Directory Template in MOSS!

wow...been a long day batteling against the site directory site template. I filled so many bug reports I will have to go through the store tommorrow and get some bug spray!
Let me start from the beggining.

The "site directory" site template is a great template with some features to catalog sharepoint sites. It includes a large "create site" button on the top of the page, and has a "sites" list that holds the links to the sites created through the "create site" link, and stores meta data on them.

So I had an idea - create a new site collection with the root as a site directory, change the name "create site" to "create project" (since my customer wanted to create project sites - nothing to do with project management...long story, but project server is out of the question) and ask the user to add custom meta data on the "project" he is creating.

Well - happily Microsoft realised this was something sharepoint 2003 lacked, and are trying to fix it. When you edit the "sites" list, and add custom fields - the site creation page shows you those fields when you open the "create site" page.
bug number One
Site directory as the root site? go figure!
Apperantly no one thought that the site directory template would be used as a root site in the site collection. otherwise, how do you explain the fact that the "create new site" button is rendering a wrong link when the template is used that way.
instead of writing the link as "/_layouts/newsbweb.aspx" it renders "//_layouts/newsbweb.aspx". This one should go directly to www.thedailywtf.com.

bug number Two
Complex controls? who wants that?
so you wanted a field called "due date". and you wanted that to be (hold your breath) of type date. you didnt expect the date picker control, did you?
...
oh, you did. pity. date fields are rendered as text boxes in the create site dialog.
And you created a lookup with a multiple selection enabled. so what?! you will still get the look up field rendered as a combobox (allowing only one item to be selected). and say thanks its not a text box like the dates!

bug number Three
Still with the custom fields. So I wanted to force a user to fill in one of the fields. is that too much to ask? but no...validation doesnt work on the cursed page.

bug number Four
Did i mention the fact that I added a lookup to another list, and set it to allow multiple selection in the "sites" list? I am sure I did. Such a scenario is probably to far-fetched, since when you fill in some data in the list, you suddenly see in the list view web part strange text next to every selection in that field: "<!-- #RENDER FAILED -->"
I wonder what thats about...

bug number Five
You have got to be kidding me!, web part communication? with a list called "sites" in a site directory template? what are you talking about???
Well - you can connect two web parts, and have one of them be the "sites" web part, and even have that one as the receiver.
but...
if the receiver "sites" web part only shows one field (the title field) I got a nice looking error: "web part error: web part sites did not implement the GetInitEventArgs".
Add another field, and viola! web part connection works again.

bug number SIX SIX SIX!
Oh, you expected sharepoint to actually store the metadata? how bizzare!
yep - what ever you do, the site meta data isnt added to the "sites" list. so long site directory.

I think I'm going to lay down for a while. tomorrow I am going to develop my own site directory list.

oh, wait - I forgot - I tried that today using the event handlers. and guess what? The bug where "itemadding" event doesnt give access to the item properties is still there. So I cant catch the event of an item being added to the "sites" list and create a site based on the metadata. I will have to create my own aspx page to do it, and update the list.

I have an feeling this isnt going to be my week...Hey Microsoft - if I had wanted to be a developer I wouldnt have become a...errr...never mind, I guess it is my job to do workarounds (-:

Update
A lot of people are asking about how it is in RTM. Well, dont bother - I contacted microsoft about this during Beta, and they acknowledged that this is a known issue and the "site directory template was not meant to work like that".
Bummer.

Thursday, September 14, 2006

New setting for MOSS Indexing performance

Now that I am upgrading to the Technical refresh, I noticed a new setting for the indexing service - "Indexer Performance" which you can set to:
  • reduced
  • partly reduced
  • maximum

The description of this setting says:

"Indexing information can place a large load on the local SQL Server database and might slow down the responsiveness of the local SharePoint sites. However, reducing the maximum allowed indexing activity will slow down the speed at which items are indexed, and therefore might cause search results to be outdated. Use information about the local server load to select the appropriate indexer performance level. "

My nerd score

I am nerdier than 48% of all people. Are you nerdier? Click here to find out!

Its refreshing!

The beta 2 technical refresh is finally available to download.
During the last few days a lot of bloggers announced its coming, but I waited for it to actually happen. And today - it did.
I will have a look at the bugs I reported for the beta 2 and verify their status on the technical refresh, and report it here!

Wednesday, September 13, 2006

Microsoft Expression - Dont install on sharepoint machines

I recently downloaded and installed Microsoft Expression Beta 1.
From first glance it looked just like SharePoint Designer. I wanted to be sure of that, and tried to install designer on the same machine. guess what? I got an error.
ok- I removed Expression from my machine and then - my sharepoint started throwing script errors at me! "Library not registered" in every page!

After crying and reparing sharepoint and even restoring the entire "12" folder, I realized when the problem started (uninstalling expression) and I knew how to fix it- I installed sharepoint designer!
This time the installation worked, and afterwards sharepoint stopped antagonizing me.

So lesson of the days - never install Expression beta one on a server running Sharepoint beta 2.

Monday, September 11, 2006

Canberra Sharepoint User Group Surprise

I am doing a 15 min presentation on user profiles in MOSS2007 in the coming Caberra SharePoint User Group meeting, and I am planning a small surprise for the group. You had better be there!
Details to follow...

Wednesday, September 06, 2006

MOSS 2007 controls - have a bit of fun with the "people editor" form control!

Many times in my web applications I need to get input from the user about other users. For example, if I am creating a task-tracking application, the user will need to assign a task to another user.
Another example is when I developed an ASP.NET2 application that connected to SAP, and had to manage user travel details. Again, I had to let the users select other users to say "I want to create a new trip for that user" (something that happens often, when secrateries fill in the forms for the managers).

If you have SharePoint 2007, you can relax and stop developing a person selector box for these applications. SharePoint has a very nice control to do exactly that. In this article I will demonstrate how to use that control in a web part - see how in two lines of code I get a world of functionality!

The Code


The object we are talking about is called PeopleEditor and it is part of the Microsoft.SharePoint.WebControls namespace.
To add it to the web part, just declare it and add it to the web part controls. Example:
        PeopleEditor p;
        protected override void CreateChildControls()
        {
            p = new PeopleEditor();
          
            this.Controls.Add(p);
            base.CreateChildControls();
        }

The Results


The control renders on the page thus:

what do we have here? a text box that allows the user to write a user name, a "check name" button to verify that name, and an "address book" button to pop up a search window:

Here we can search for a person, and return the results to the text box we started from.

If the user typed a user name and used the "check name" button, he will be shown if the user name is valid or not, and may click on the invalid name to get "more names" options:

Now, how can we customize this to our form's needs?
you can:

  • use ".AllowEmpty" to specify if the user must fill the contorl
  • use ".AllowTypeIn" to specify if the user can type the wanted user name in the text box, or if he must use the search pop up
  • use ".MultiSelect" to specify if the user can select multiple people in the control.
  • use ".PrincipalSource" to specify where the control will look for users (if you have more than one source of users...)
  • use ".PlaceButtonsUnderEntityEditor" to specify if the "check name" and "address book" buttons will be on the same line with the text box, or underneath:
  • use ".SharePointGroup" to filter the people the user can select to be only people from a specific group defined in the site.

There are more options, but you will have to play around with them yourself. Unfortunately, Microsoft didnt release (yet) any documentation on the control and its use, so its up to us to find out and share our findings!!!
Have fun!