2
votes

I've looked around and haven't found a solution yet. I have picked up code snippets here and there to find a solution.

I have a Doc Library called "Document Collaboration" with the field "Assigned To". This is a People/Groups field. These people will be able to work on a specific document(list item permission). Now, at first, they will have hidden permissions(they cant see it), but when added to the doc, they will see it and be able to contribute it, also they will get an email notification. I have attached the full code below.

So, I don't get any errors, when I go through VS10 debug. But it doesn't send any email or doesn't set the permissions. What's wrong?

using System;
using System.IO;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;

namespace ARDT.Notifications
{
    /// <summary>
    /// List Item Events
    /// </summary>
    public class Notifications : SPItemEventReceiver
    {
       /// <summary>
       /// An item was checked in
       /// </summary>
       public override void ItemCheckedIn(SPItemEventProperties properties)
       {
           SPSite site = new SPSite("http://sp2010dev/ardt");
           using (SPWeb web = site.OpenWeb())
           {
               SPList list = web.Lists["Document Collaboration"];
               SPListItem listItem = properties.ListItem;
               SPUser userName = null;
               String toAddress = null;

               //EMail initializations
               bool appendHtmlTag = false;
               bool htmlEncode = false;
               string subject = "Subject";
               string message = "Message text";

               //get usernames
               string[] userNameArray = listItem.Fields["Assigned to"].ToString().Split(';');

               for (int i = 0; i <= userNameArray.Length - 1; i++)
               {
                   userName = web.AllUsers[userNameArray[i]];
                   toAddress = userName.Email;
                   SPSecurity.RunWithElevatedPrivileges(delegate()
                   {
                       //EMAIL USER
                       bool result = SPUtility.SendEmail(web, appendHtmlTag, htmlEncode, toAddress, subject, message);

                       //PERMISSIONS
                       //remove permissions first
                       web.AllowUnsafeUpdates = true;
                       listItem.BreakRoleInheritance(false);
                       SPRoleAssignmentCollection raCollection = listItem.RoleAssignments;
                       //remove exisiting permissions one by one
                       for (int a = raCollection.Count - 1; i > -0; i--)
                       {
                           raCollection.Remove(a);
                       }

                       //grant permissions for specific list item
                       SPRoleDefinition roleDefintion = web.RoleDefinitions.GetByType(SPRoleType.Contributor);
                       SPRoleAssignment roleAssignment = new SPRoleAssignment(userName);

                       roleAssignment.RoleDefinitionBindings.Add(roleDefintion);
                       listItem.RoleAssignments.Add(roleAssignment);
                       listItem.Update();
                   });
               }
           }
           base.ItemCheckedIn(properties);
       }
    }
}
2

2 Answers

5
votes

nope, I made the simple mistake of putting it under checked in instead of updated, there's also a work around for the function being run multiple times when it updates, just make a column called "updateContributors" in your list and default value True/Yes

Here's the code/no time to explain, but pretty commented, good luck:

    using System;
    using System.IO;
    using System.Security.Permissions;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Security;
    using Microsoft.SharePoint.Utilities;
    using Microsoft.SharePoint.Workflow;

    //Debugging includes
    using System.Diagnostics;


    namespace ARDT.Notifications
    {
        /// <summary>
        /// List Item Events
        /// </summary>
        public class Notifications : SPItemEventReceiver
        {
            /// <summary>
            /// An item was updated
            /// </summary>
            public override void ItemUpdated(SPItemEventProperties properties)
            {
                if (properties.ListItem["updateContributors"].ToString().Equals("True"))
                {
                    //work around so it goes through it only once instead of everytime the item is updated
                    properties.ListItem["updateContributors"] = "False";
                    SPSite site = new SPSite("http://sp2010dev/ardt/");
                    using (SPWeb web = site.OpenWeb())
                    {

                        SPList list = web.Lists["Document Collaboration"];
                        SPListItem listItem = properties.ListItem;
                        SPUser userName = null;
                        String toAddress = null;

                        //EMail initializations
                        bool appendHtmlTag = false;
                        bool htmlEncode = false;
                        string subject = "You have been assigned to a Document";
                        string message = "Test Message";

                        //get usernames
                        string tempFieldValue = listItem["Assigned To"].ToString();
                        string[] userNameArray = listItem["Assigned To"].ToString().Split(';');

                        //remove permissions first
                        web.AllowUnsafeUpdates = true;
                        listItem.BreakRoleInheritance(false);
                        SPRoleAssignmentCollection raCollection = listItem.RoleAssignments;
                        //remove exisiting permissions one by one
                        for (int a = raCollection.Count - 1; a >= 0; a--)
                        {
                            raCollection.Remove(a);
                        }

                        for (int i = 1; i < userNameArray.Length; i++)
                        {
                            tempFieldValue = userNameArray[i].Replace("#", "");
                            userName = web.AllUsers[tempFieldValue];
                            toAddress = userName.Email;
                            SPSecurity.RunWithElevatedPrivileges(delegate()
                            {
                                //EMAIL USER
                                bool result = SPUtility.SendEmail(web, appendHtmlTag, htmlEncode, toAddress, subject, message);

                                //PERMISSIONS                              
                                //grant permissions for specific list item
                                SPRoleDefinition roleDefintion = web.RoleDefinitions.GetByType(SPRoleType.Contributor);
                                SPRoleAssignment roleAssignment = new SPRoleAssignment(userName);

                                roleAssignment.RoleDefinitionBindings.Add(roleDefintion);
                                listItem.RoleAssignments.Add(roleAssignment);
                                listItem.Update();
                            });
                            i++;
                        }

                    }
                    //base.ItemUpdated(properties);
                    //after final update has been done return true
                    properties.ListItem["updateContributors"] = "True";
                }
            }



        }

    }
1
votes

One of the problems you have in your code - you create the SPWeb object in current execution context, but then try to send mail using SPSecurity.RunWithElevatedPrivileges. You should never open the web with one account and then use it in another. You have to re-create the context in RunWithElevatedPrivileges block as it can be seen in this example.