Wednesday, August 12, 2009

How do I tell what the next list item ID is?

By Roi Kolbinger - SharePoint Consultant
KWizCom Professional Services –
http://www.kwizcom.com/


If you have ever worked with Event Handlers on an item you probably came across the same problem that was bothering me…

I created a ListItem and used the event handler ItemAdding (for a synchronic event). I tried to find out what my ID was but the value I got was zero.

This problem will not occur on ItemAdded (of a non-synchronic event) because the item is created separately and it has its own ID.

If you use the code below on ItemAdding,you will get a zero value on listItem ID.

SPList list = web.Lists[properties.ListId];
SPListItem listItem = list.Items[properties.ListItem.UniqueId];
int itemId = listItem.ID; // itemId always zero on ItemAdding event


To discover the ID (and avoid getting the zero value) of my synchronic event I wrote this code:

int itemId = list.Items[list.ItemCount - 1].ID + 1;

This code will work well as long as you do not delete the last item and do not add more than one item simultaneously. If you do the sum you will get will be incorrect.

I searched for a SharePoint API that would give me the next item ID but found none. It seemed no one had tackled this problem….

After extensive searching I found a solution, brilliant in its simplicity. This is the code:

///
/// Get the next available item id from a list
///

/// < name="site">site
/// < name="listId">listId
/// <>
public static int NextItemID(SPSite site, Guid listId(
{
int id = -1;
Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(delegate()
{
if (site.WebApplication.ContentDatabases.Count > 0(
{
string DBConnString = site.WebApplication.ContentDatabases[0].DatabaseConnectionString;
SqlConnection con = new SqlConnection(DBConnString);
try
{
con.Open();
SqlCommand com = con.CreateCommand();
com.CommandText = String.Format("select tp_NextAvailableId from AllLists where tp_ID = '{0}'", listId.ToString());
id = (int)com.ExecuteScalar();
}
finally
{
con.Close();
}
}
});
return id;
}

...
int itemId = NextItemID(new SPSite(properties.SiteId), properties.ListId);


As you can see, the solution is to connect to the MOSS database and read the ID AllList table. All the information was right there, we simply had to access it.

Now you know how to get the next ID of the ListItem and (hopefully!) Event Handlers will no longer give you any trouble!...

Credits:
The solution detailed in this article was found at:
http://suguk.org/forums/permalink/6226/13513/ShowThread.aspx

Tuesday, July 21, 2009

How to register safe control to web.config manually

Here is a little code example I found at MSDN that allows you to add a safe control to the web application web.config file throughout the SharePoint farm.

It uses the SPWebConfigModification class to add the change and will, make sure your changes gets re-applied whenever a new web application is created in the farm!

Note, you can add all sorts of modifications using this class - not only safe controls.
As Daniel Larson wrote in the comments for the MSDN article, for web controls - if possible you should use other methods of deployment and update the safe control in the manifest xml file.

taken from: msdn SPWebConfigModification

SPWebService myService = SPWebService.ContentService;

SPWebConfigModification myModification = new SPWebConfigModification();
myModification.Path = "configuration/SharePoint/SafeControls";
myModification.Name = "SafeControl[@Assembly='MyCustomAssembly'][@Namespace='MyCustomNamespace'][@TypeName='*'][@Safe='True']";
myModification.Sequence = 0;
myModification.Owner = WebConfigModificationFeatureReceiver.OwnerId;
myModification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
myModification.Value = "";

myService.WebConfigModifications.Add(myModification);
myService.Update();
myService.ApplyWebConfigModifications();


I found that usefull when a customer of ours wanted to use a custom field inside a publishing page layout... the original installer did not add the safe control since you dont need it when you are inside list item form (create/edit/view), but inside a publishing page layout we got a message saying the control is not registered as safe.

Hope you do to, Shai.

Monday, July 20, 2009

Helpful batch file command for installers

Hi,

Just a short one this time,

here is a nice script for looping through all MSI files in current folder / sub folders and running the installers one after the other.

Just paste this into a install.bat file and place with your set of installers:
for /f "delims=" %%a IN ('dir /s /b *.msi') do MSIEXEC /i "%%a"

simple, 1 line of script made my life easier with WikiPlus.

You see, installing it involves running installers for 5 different products so this way I just throw them into sub folders and this little script does the rest for me.

:)

Enjoy,