List Item multiple users permissions programatical

2019-04-13 05:56发布

问题:

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 dont 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);
           }

        }
    }

回答1:

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";
                }
            }



        }

    }


回答2:

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.