Get Calendar List Item GUID

I downloaded code for a reservation event receiver from here:  http://blog.sharepointsydney.com.au/post/Setting-up-multiple-calendars-for-meeting-room-bookings-prevent-double-booking.aspx

However, on the ItemUpdating it throws an "Object Reference Not Set to an Instance of an Object" error.  By commenting out parts of the code and re-deploying I have narrowed the issue down to the line that gets the item's GUID:

string guid_internal = collItems.List.Fields["GUID"].InternalName;

When I modify it to something like "UniqueId" I get the "Value does not fall within expected range" error.  Is there a better way to obtain the GUID of the calendar list item - or am I missing something?  Full code below:

using System;
using Microsoft.SharePoint;


namespace Webcoda.WSS.Calendar.Events
{
    class PreventDoubleBooking: SPItemEventReceiver
    {
        /// <summary>
        /// This event is triggered when the user adds a new item
        /// </summary>
        /// <param name="properties"></param>
        public override void ItemAdding(SPItemEventProperties properties)
        {
            //Our query string variable
            string strQuery = null;

            try
            {
                //Get the Sharepoint site instance
                using (SPWeb oWebsite = new SPSite(properties.SiteId).OpenWeb(properties.RelativeWebUrl))
                {
                    
                    //Get the collection of properties for the Booking item
                    SPListItemCollection collItems = oWebsite.Lists[properties.ListTitle].Items;

                    //Get the Calendar List that we will be querying against
                    SPList calendar = oWebsite.Lists[properties.ListId];

                    //Get the internal name of the fields we are querying. 
                    //These are required for the CAML query
                    string start_internal = collItems.List.Fields["Start Time"].InternalName;
                    string end_internal = collItems.List.Fields["End Time"].InternalName;
                    string MeetingRoom_Internal = collItems.List.Fields["Meeting Room"].InternalName;

                    //Get the query string parameters
                    string start_str = properties.AfterProperties[start_internal].ToString();
                    string end_str = properties.AfterProperties[end_internal].ToString();
                    string MeetingRoom_str = properties.AfterProperties[MeetingRoom_Internal].ToString();

                    //Construct a CAML query
                    SPQuery query = new SPQuery();

                    //Create the CAML query string that checks to see if the booking we are attemping
                    //to add will overlap any existing bookings
                    strQuery = string.Format(@"

	<Where>
	
		<And>
			<Or>
			
				<Or>
		            <And>
		               <Leq>
		                  <FieldRef Name='EventDate' />
		                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{0}</Value>
		               </Leq>

		               <Gt>
		                  <FieldRef Name='EndDate' />
		                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{0}</Value>
		               </Gt>
		            </And>

		            <And>
		               <Lt>
		                  <FieldRef Name='EventDate' />
		                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{1}</Value>
		               </Lt>

		               <Geq>
		                  <FieldRef Name='EndDate' />
		                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{1}</Value>
		               </Geq>
		            </And>
				</Or>
				
				<Or>
		            <And>
		               <Leq>
		                  <FieldRef Name='EventDate' />
		                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{0}</Value>
		               </Leq>

		               <Geq>
		                  <FieldRef Name='EndDate' />
		                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{1}</Value>
		               </Geq>
		            </And>

		            <And>
		               <Geq>
		                  <FieldRef Name='EventDate' />
		                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{0}</Value>
		               </Geq>

		               <Leq>
		                  <FieldRef Name='EndDate' />
		                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{1}</Value>
		               </Leq>
		            </And>
				</Or>
				
			</Or>
		
			<Eq>
				<FieldRef Name='Meeting_x0020_Room' />
				<Value Type='Choice'>{2}</Value>
			</Eq>
			
		</And>
		
	</Where>
    <OrderBy>
		<FieldRef Name='EventDate' />
	</OrderBy>
", start_str, end_str, MeetingRoom_str);

                    //Set the query string for the SPQuery object
                    query.Query = strQuery;

                    //Execute the query against the Calendar List
                    SPListItemCollection existing_events = calendar.GetItems(query);
                    
                    //Check to see if the query returned any overlapping bookings
                    if (existing_events.Count > 0)
                    {
                        //Cancels the ItemAdd action and redirects to error page
                        properties.Cancel = true;

                        //Edit the error message that will display on the error page
                        properties.ErrorMessage += "This booking cannot be made because of one or more bookings in conflict. <BR><BR>";

                        //Here you can loop through the results of the query
                        //foreach (SPListItem oListItem in existing_events)
                        //{
                        //   ....
                        //}

                        properties.ErrorMessage += "Please go back and schedule a new time.";
                    }
                    
                }
            }
            catch (Exception ex)
            {
                //Cancels the ItemAdd action and redirects to error page
                properties.Cancel = true;

                //Edit the error message that will display on the error page
                properties.ErrorMessage = "Error looking for booking conflicts: " + ex.Message;
            }

          
        }

        /// <summary>
        /// This event is triggered when the user edits an calendar item
        /// </summary>
        /// <param name="properties"></param>
        public override void ItemUpdating(SPItemEventProperties properties) {

            string strQuery = null;

            try {

                //Get the Sharepoint site instance
                using (SPWeb oWebsite = new SPSite(properties.SiteId).OpenWeb(properties.RelativeWebUrl)) {

                    //Get the collection of properties for the Booking item
                    SPListItemCollection collItems = oWebsite.Lists[properties.ListTitle].Items;

                    //Get the Calendar List that we will be querying against
                    SPList calendar = oWebsite.Lists[properties.ListId];                  

                    //Get the internal name of the fields we are querying. 
                    //These are required for the CAML query
                    string start_internal = collItems.List.Fields["Start Time"].InternalName;
                    string end_internal = collItems.List.Fields["End Time"].InternalName;
                    string MeetingRoom_Internal = collItems.List.Fields["Meeting Room"].InternalName;
                    string guid_internal = collItems.List.Fields["GUID"].InternalName;

                    //Get the query string parameters
                    string start_str = properties.AfterProperties[start_internal].ToString();
                    string end_str = properties.AfterProperties[end_internal].ToString();
                    string MeetingRoom_str = properties.AfterProperties[MeetingRoom_Internal].ToString();
                    string guid_str = properties.AfterProperties[guid_internal].ToString();

                    //Construct a CAML query
                    SPQuery query = new SPQuery();

                    //Create the CAML query string that checks to see if the booking we are attemping
                    //to change will overlap any existing bookings, OTHER THAN ITSELF
                    strQuery = string.Format(@"

	<Where>
		<And>
		
			<And>
				<Or>
				
					<Or>
			            <And>
			               <Leq>
			                  <FieldRef Name='EventDate' />
			                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{0}</Value>
			               </Leq>

			               <Gt>
			                  <FieldRef Name='EndDate' />
			                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{0}</Value>
			               </Gt>
			            </And>

			            <And>
			               <Lt>
			                  <FieldRef Name='EventDate' />
			                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{1}</Value>
			               </Lt>

			               <Geq>
			                  <FieldRef Name='EndDate' />
			                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{1}</Value>
			               </Geq>
			            </And>
					</Or>
					
					<Or>
			            <And>
			               <Leq>
			                  <FieldRef Name='EventDate' />
			                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{0}</Value>
			               </Leq>

			               <Geq>
			                  <FieldRef Name='EndDate' />
			                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{1}</Value>
			               </Geq>
			            </And>

			            <And>
			               <Geq>
			                  <FieldRef Name='EventDate' />
			                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{0}</Value>
			               </Geq>

			               <Leq>
			                  <FieldRef Name='EndDate' />
			                  <Value Type='DateTime' IncludeTimeValue='TRUE'>{1}</Value>
			               </Leq>
			            </And>
					</Or>
					
				</Or>
			
				<Eq>
					<FieldRef Name='Meeting_x0020_Room' />
					<Value Type='Choice'>{2}</Value>
				</Eq>
				
			</And>
		
			<Neq>
				<FieldRef Name='GUID' />
				<Value Type='GUID'>{3}</Value>
			</Neq>
		
		</And>
		
	</Where>
	
	<OrderBy>
		<FieldRef Name='EventDate' />
	</OrderBy>
", start_str, end_str, MeetingRoom_str, guid_str);

                    //Set the query string for the SPQuery object
                    query.Query = strQuery;

                    //Execute the query against the Calendar List
                    SPListItemCollection existing_events = calendar.GetItems(query);

                    //Check to see if the query returned any overlapping bookings
                    if (existing_events.Count > 0)
                    {
                        //Cancels the ItemAdd action and redirects to error page
                        properties.Cancel = true;

                        //Edit the error message that will display on the error page
                        properties.ErrorMessage += "This booking cannot be made because of one or more bookings in conflict. <BR><BR>";

                        //Here you can loop through the results of the query
                        //foreach (SPListItem oListItem in existing_events)
                        //{
                        //   ....
                        //}

                        properties.ErrorMessage += "Please go back and schedule a new time.";
                    }
                }
            }
            catch (Exception ex) 
            {

                //Cancels the ItemAdd action and redirects to error page
                properties.Cancel = true;

                //Edit the error message that will display on the error page
                properties.ErrorMessage = "Error looking for booking conflicts: " + ex.Message;
            }
        }        
    }
}

March 8th, 2012 6:14pm

Hi Melissa,

I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.

Thanks

Free Windows Admin Tool Kit Click here and download it now
March 12th, 2012 11:06am

Hi there,

Please verify the internal name of column which you have hardcoded in the code i.e 

string start_internal = collItems.List.Fields["Start Time"].InternalName; string end_internal = collItems.List.Fields["End Time"].InternalName;

I have used the Room reservation template from MSDN which has provided by MS under the code name of "Fantastic 40" along with below James Finn article.

http://www.codeproject.com/Articles/30983/SharePoint-Reservations

It worked for me for reservation. 

March 12th, 2012 11:39am

Thank you for your response.  The Start Time and End Time fields are ok.  It's just the GUID in the ItemUpdating event of the code that errors.  It appears that the get InternalName only likes using columns that are not the builtin / hidden columns.  I tried using just the ID column and that errored as well. 

I have used the Fab 40 Room Reservation but it does not support the recurring events, so it is not suitable.  I have also used the James Finn but it has issues of it's own as well.  The newest version of it (which luckily I haven't installed) is not looking for conflicts with rooms in the year 2012.  I could never get the Resource column in it to work so I made a work around of using separate calendars for separate rooms and then rolling them up into 1 list but that has become messy overtime and also has issues with recurring events not updating correctly.

So, after all that I'm looking for a new, fresh solution.  If I can just get the ItemUpdating event to work properly I'll be all set.  I'm not a programmer by any means, I'm 100% self-taught and still have a lot to learn.  I have been programming for a couple of years now so I'm not a complete newbie but I definitely don't know as much as I would like to. 

I'm thinking with the GUID I should take out the code to get the Internal name and maybe hardocde the internal name into the following line:

string guid_str = properties.AfterProperties[guid_internal].ToString();

Free Windows Admin Tool Kit Click here and download it now
March 12th, 2012 3:49pm

Should try using AfterProperties http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spitemeventproperties.afterproperties.aspx

March 17th, 2012 3:47am

Hello,

Your code is wrong.

Erase:

string guid_internal = collItems.List.Fields["GUID"].InternalName;

Rename:

string guid_str = properties.AfterProperties[guid_internal].ToString();

to

string guid_str = properties.ListItem.UniqueId.ToString();

Erase

<Neq>
				<FieldRef Name='GUID' />
				<Value Type='GUID'>{3}</Value>
			</Neq>

That's all. It must to work fine.

I hope it's help you.

Free Windows Admin Tool Kit Click here and download it now
February 12th, 2013 3:27pm

Hi,

Please try this, it works for me.

remove string guid_str = properties.AfterProperties[guid_internal].ToString();

use string guid_str = properties.ListItem.UniqueId.ToString();

No change in Query.


February 4th, 2014 7:24am

This dint work for me.

What worked for  was :

//commented the below lines

//string MeetingRoom_Internal = collItems.List.Fields["Meeting Room"].InternalName;

//string MeetingRoom_str = properties.AfterProperties[MeetingRoom_Internal].ToString();

//added the below line :

string MeetingRoom_str = proerties.AfterProperties["Meeting_x0020_Room0"].ToString();

///Change completed

The issue was that the code was  not  being able to fetch the InternalName . So i hardcoded the same . You can fetch internal name using the steps shown in blog :

https://social.msdn.microsoft.com/Forums/sharepoint/en-US/75ca6fab-56f3-4bf4-aae0-2d29821778a2/how-to-get-internal-names-of-columns-in-sharepoint-lists

Worth a try . Hop this helps .

Free Windows Admin Tool Kit Click here and download it now
April 24th, 2015 2:48am

worked great for . I have a similar solution
April 24th, 2015 2:52am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics