none
Can I add request comment when joining group? RRS feed

  • Question

  • I want to customize FIM's dialog which is shown when user creates "join group" request. I want that this dialog will looks like one of these:

    Variant 1

    Variant 2

    Experts in FIM, is it possible?

    Wednesday, September 19, 2012 6:39 PM

Answers

  • Yes, but it is not a very straight forward modification. You cannot modify the existing pages because they are compiled FIM controls. You need to mimic the functionality of the existing controls and add your custom modifications.

    First, you need to backup and modify the site pages to load an IFRAME pointing to a custom aspx page.
    Site Pages are located in FEATURES\MSILM2SitePages\aspx\groups [AddMembers.aspx and JoinGroups.aspx]

    Create your custom aspx pages under your LAYOUTS\custom folder, [AddMembers.aspx and JoinGroups.aspx]
    These pages will need to read and process the Page Cache properties stored in the object of the CacheID querystring parameter of the Referring Page. Read the "DisplayName", "TypeName" and "Id" properties of the Cache object and use those to build a Put request to the FIM web service. This can be done through the FIM Resource Management Client available on CodePlex here.

    You'll need to add an Indexed-String attribute to your Group resource to hold the comment text.

    Create a custom Authorization workflow activity to read the comment text and add it to the Request Details of the Request so it can be displayed to the Approver(s). You can use this to require a comment to be entered.

    After the Request is Approved, you'll need to add a custom Action workflow activity to clear out the comment attribute on the Group Resource.

    If you are not looking to get this involved in the inner working of FIM... This exact functionality has already been built and tested. Contact someone from here and inquire about "Business Justification for Custom Group Membership Add Requests" via email: info@BlueVaultSoftware.com

    • Marked as answer by Pavel Lipanov Monday, September 24, 2012 2:07 PM
    Thursday, September 20, 2012 3:48 PM

All replies

  • Yes, but it is not a very straight forward modification. You cannot modify the existing pages because they are compiled FIM controls. You need to mimic the functionality of the existing controls and add your custom modifications.

    First, you need to backup and modify the site pages to load an IFRAME pointing to a custom aspx page.
    Site Pages are located in FEATURES\MSILM2SitePages\aspx\groups [AddMembers.aspx and JoinGroups.aspx]

    Create your custom aspx pages under your LAYOUTS\custom folder, [AddMembers.aspx and JoinGroups.aspx]
    These pages will need to read and process the Page Cache properties stored in the object of the CacheID querystring parameter of the Referring Page. Read the "DisplayName", "TypeName" and "Id" properties of the Cache object and use those to build a Put request to the FIM web service. This can be done through the FIM Resource Management Client available on CodePlex here.

    You'll need to add an Indexed-String attribute to your Group resource to hold the comment text.

    Create a custom Authorization workflow activity to read the comment text and add it to the Request Details of the Request so it can be displayed to the Approver(s). You can use this to require a comment to be entered.

    After the Request is Approved, you'll need to add a custom Action workflow activity to clear out the comment attribute on the Group Resource.

    If you are not looking to get this involved in the inner working of FIM... This exact functionality has already been built and tested. Contact someone from here and inquire about "Business Justification for Custom Group Membership Add Requests" via email: info@BlueVaultSoftware.com

    • Marked as answer by Pavel Lipanov Monday, September 24, 2012 2:07 PM
    Thursday, September 20, 2012 3:48 PM
  • Thank you for reply! I'll try it tomorrow and report about success of the solution.
    Thursday, September 20, 2012 4:54 PM
  • Hi, mgercevich!

    You are absolutely right with solution. I checked it out. It works for me! Thank you!

    Monday, September 24, 2012 2:07 PM
  • Hi Pavel and mgercevich,

    I have the same need!

    Is it possible to have you developped page to test it?

    Thank you.

    Thursday, January 10, 2013 5:15 PM
  • I'll warn you right now that this is a rather tricky configuration to setup and test...The AddMembers replacement is exponentially more complex due to the need of performing Member searches and look-ups.

    First, you will absolutely need the Microsoft.ResourceManagement.Client on CodePlex to talk to the FIM web service. The easiest installation is to GAC the two assemblies and modify your web.config to resolve your endpoints.

    You will also need to develop a custom Authorization workflow activity to read the comment value and set the comment on the Request Details property of the current Request object, and a custom Action workflow activity to clear the comment field on the Group resource after the member is added to the group. -- The contact information in my original post would get you in contact with someone that already has both of these developed for purchase, or PM me with your contact info and I'll get someone to contact you.

    In the example below, I have defined the comment field as BusinessJustification.

    Your JoinGroups.aspx under your FEATURES folder should be backed-up and replaced with something like:

    <%@ Page masterpagefile="../../_catalogs/masterpage/submission.master" language="C#" inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" meta:progid="SharePoint.WebPartPage.Document" UICulture="auto" Culture="auto" %>
    <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
    <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
    <%@ Import Namespace="Microsoft.SharePoint" %> 
    <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    
    <asp:Content id="content1" ContentPlaceHolderID="PlaceHolderMain" runat="server">
    	<iframe src="/_layouts/Custom/JoinGroups.aspx" height="100%" width="100%"></iframe>
    </asp:Content>

    Which loads your Custom/JoinGroups.aspx under your LAYOUTS folder:

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="JoinGroups.aspx.cs" Inherits="Custom.IdentityManagement.WebUI.LAYOUTS.Custom.JoinGroups" %>
    <%@ Assembly Name="Microsoft.ResourceManagement.Client, Version=1.5.3.0, Culture=neutral, PublicKeyToken=39bb8ee051128c99" %>
    <%@ Assembly Name="Microsoft.ResourceManagement.ObjectModel, Version=1.5.3.0, Culture=neutral, PublicKeyToken=39bb8ee051128c99" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" runat="server">
        <title>Forefront Identity Manager</title>
        <link href="/_layouts/1033/styles/core.css" rel="stylesheet" type="text/css"/>
        <link id="onetidThemeCSS" href="/IdentityManagement/_themes/FIM/FIM1011-65001.css" rel="stylesheet" type="text/css"/>
        <style type="text/css">
            .btnDisabled 
            {
            	color: #989898 !important;
            }
        </style>
        <script type='text/javascript'>
            function btnSubmit_ClientClick(Client) {
                if (Client.className.indexOf('btnDisabled') > 0) {
                    return false;
                }
                else {
                    Client.className += ' btnDisabled';
                    Client.value = 'Processing...';
                }
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server" onreset="return false;">
        <table style="height: 100%; width: 100%;" id="MSO_ContentTable" border="0" cellspacing="0" cellpadding="0">
            <tbody>
                <tr>
                    <td height="100%" class="ms-bodyareacell" valign="top">
                        <span id="PlaceHolderMain_JoinGroups">
                            <span>
                                <div id="root" style="width: 100%; height: 100%; ; z-index: 5001;">
                                    <div id="updatePanel">
                                        <table class="ms-pagetitleareaframe" width="100%" cellspacing="0" cellpadding="6">
                                            <tbody>
                                                <tr>
                                                    <td class="commonControlsCellTitle ms-titleareaframe" style="padding: 0 0 0 0;">
                                                        <div id="FormHeader">
                                                            <div style="color:#323232; padding-left: 10px; height: 37px; background- top; background-repeat: repeat-x; background-color: rgb(234, 243, 255); background-image: url('/_layouts/images/MSILM2/homepage_shade_corporate.png') !important; text-align: left;">
                                                                <span style="color: #718395; 
                                                                    text-align: left; 
                                                                    padding: 10px 10px 10px 0px; 
                                                                    font-size: 18px; 
                                                                    margin: 8px 8px 8px 8px;">Join Groups</span>
                                                            </div>
                                                        </div>
                                                    </td>
                                                </tr>
                                            </tbody>
                                        </table>
                                        <span id="requestSummary">
                                            <table width="100%" class="ms-propertysheet" cellspacing="0" cellpadding="6">
                                                <tbody>
                                                    <!-- Instructions -->
                                                    <tr>
                                                         <td width="25%" colspan="1" style="vertical-align: top; border-bottom: solid 1px #d8d8d8;" >
                                                            <div style="text-align: right;">
                                                                <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                    font-size: 12px;">Instructions</span>
                                                            </div>
                                                        </td>
                                                        <td width="1%" colspan="1" style="vertical-align: top; border-bottom: solid 1px #d8d8d8;" >
                                                            <div style="text-align: right;">
                                                                <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                    font-size: 12px; 
                                                                    color: #ff0000;">&nbsp;</span>
                                                            </div>
                                                        </td>
                                                        <td colspan="1" style="vertical-align: top; border-bottom: solid 1px #d8d8d8;" >
                                                            Enter the <i>Business Justification</i> for requesting membership to the listed groups.
                                                        </td>
                                                   </tr>
                                                   <!-- Controls -->
                                                    <tr>
                                                        <td width="25%" colspan="1" style="vertical-align: top; border-bottom: solid 1px #d8d8d8;" >
                                                            <div style="text-align: right;">
                                                                <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                    font-size: 12px;"
                                                                    title="List of groups to request membership." >Groups</span>
                                                            </div>
                                                        </td>
                                                        <td width="1%" colspan="1" style="vertical-align: top; border-bottom: solid 1px #d8d8d8;" >
                                                            <div style="text-align: right;">
                                                                <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                    font-size: 12px; color: #ff0000;">&nbsp;</span>
                                                            </div>
                                                        </td>
                                                        <td colspan="1" style="vertical-align: top; border-bottom: solid 1px #d8d8d8;" >
                                                            <asp:Listbox ID="ctrlGroups" runat="server" Enabled="false" Width="300px" Visible="false" />
                                                        </td>
                                                    </tr>
                                                    <!-- Last Control -->
                                                    <tr>
                                                        <td width="25%" colspan="1" style="vertical-align: top;" >
                                                            <div style="text-align: right;">
                                                                <span class="ms-formlabel" style="color:maroon; border-top-width: 0px; 
                                                                    font-size: 14px; font-weight:bold;" id="lblInfoLabel" runat="server"
                                                                    title="Business reason for membership request(s)." >Business Justification</span>
                                                            </div>
                                                        </td>
                                                        <td width="1%" colspan="1" style="vertical-align: top;" >
                                                            <div style="text-align: right;">
                                                                <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                    font-size: 12px; color: #ff0000;">*</span>
                                                            </div>
                                                        </td>
                                                        <td colspan="1" style="vertical-align: top;">
                                                            <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                    font-size: 12px; font-weight:normal;" id="lblInfoReasonLabel" runat="server"
                                                                    title="Select a business reason for membership request(s)." >Reason?</span><br />
                                                            <asp:DropDownList ID="ddlReason" runat="server" Width="300px">
                                                                <asp:ListItem Text="Please Select a Reason..." Value="" />
                                                                <asp:ListItem Text="Additional Job Responsibility" Value="Additional Job Responsibility" />
                                                                <asp:ListItem Text="Job Change" Value="Job Change" />
                                                                <asp:ListItem Text="New Hire" Value="New Hire" />
                                                                <asp:ListItem Text="New System or Process" Value="New System or Process" />
                                                                <asp:ListItem Text="Temporary back-up" Value="Temporary back-up" />
                                                                <asp:ListItem Text="Other" Value="Other" />
                                                            </asp:DropDownList><br /><br />
                                                            <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                    font-size: 12px; font-weight:normal;" id="lblInfoAllowLabel" runat="server"
                                                                    title="Enter specific additional reason text for membership request(s)." >Info?</span><br />
                                                            <asp:TextBox ID="txtReason" runat="server" Width="300px" MaxLength="256" /><br />
                                                            <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                    font-size: 10px; font-weight:normal;">("to do my job" is not an acceptable answer)</span>
                                                        </td>
                                                    </tr>
                                                   <!-- Error Message -->
                                                   <tr id="trErrorRow" runat="server" style="display: none;">
                                                        <td colspan="3" style="padding-left: 28px; 
                                                            color: #ff0000;"><asp:Literal ID="txtErrorText" runat="server" /></td>
                                                   </tr>
                                                </tbody>
                                            </table>
                                            <table id="StatusTable" runat="server" visible="false" width="100%" border="0" >
                                                <tr>
                                                    <td colspan="3">&nbsp;<br /><br />&nbsp;</td>
                                                </tr>
                                                <tr>
                                                    <td width="25%" colspan="1" style="vertical-align: top; border-top: solid 1px #d8d8d8;" >
                                                        <div style="text-align: right;">
                                                            <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                font-size: 12px;"
                                                                title="Submitted membership requests." >Submitted</span>
                                                        </div>
                                                    </td>
                                                    <td width="1%" colspan="1" style="vertical-align: top; border-top: solid 1px #d8d8d8;" >
                                                        <div style="text-align: right;">
                                                            <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                font-size: 12px; color: #ff0000;">&nbsp;</span>
                                                        </div>
                                                    </td>
                                                    <td colspan="1" style="vertical-align: top; border-top: solid 1px #d8d8d8;" >
                                                        <asp:Table id="tblSuccess" runat="server" Width="95%" CellSpacing="0" >
                                                            <asp:TableRow ID="tblSuccessHeadRow" runat="server"> 
                                                                <asp:TableCell ID="tblSuccessHeadCell1" runat="server" style="background-color: rgb(235, 235, 235); 
                                                                    color: Black; text-align: center; border: solid 1px black;" 
                                                                    Width="25%" >Group</asp:TableCell>
                                                                <asp:TableCell ID="tblSuccessHeadCell2" runat="server" style="background-color: rgb(235, 235, 235); 
                                                                    color: Black; text-align: center; border: solid 1px black;"
                                                                    Width="75%" >Status</asp:TableCell>
                                                            </asp:TableRow>
                                                        </asp:Table>
                                                    </td>
                                                </tr>
                                                <tr>
                                                    <td width="25%" colspan="1" style="vertical-align: top; border-top: solid 1px #d8d8d8;" >
                                                        <div style="text-align: right;">
                                                            <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                font-size: 12px;"
                                                                title="Denied membership requests.">Not Submitted</span>
                                                        </div>
                                                    </td>
                                                    <td width="1%" colspan="1" style="vertical-align: top; border-top: solid 1px #d8d8d8;" >
                                                        <div style="text-align: right;">
                                                            <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                font-size: 12px; color: #ff0000;">&nbsp;</span>
                                                        </div>
                                                    </td>
                                                    <td colspan="1" style="vertical-align: top; border-top: solid 1px #d8d8d8;" >
                                                        <asp:Table id="tblFail" runat="server" Width="95%" CellSpacing="0" >
                                                            <asp:TableRow ID="tblFailHeadRow" runat="server"> 
                                                                <asp:TableCell ID="tblFailHeadCell1" runat="server" style="background-color: rgb(235, 235, 235); 
                                                                    color: Black; text-align: center; border: solid 1px black;" 
                                                                    Width="25%" >Group</asp:TableCell>
                                                                <asp:TableCell ID="tblFailHeadCell2" runat="server" style="background-color: rgb(235, 235, 235); 
                                                                    color: Black; text-align: center; border: solid 1px black;"
                                                                    Width="75%" >Status</asp:TableCell>
                                                            </asp:TableRow>
                                                        </asp:Table>
                                                    </td>
                                                </tr>
                                            </table>
                                        </span>
                                
                                        <div class="commonFooterRow" id="FormFooter" style="; bottom:0;">
                                            <table class="ms-propertysheet" cellspacing="0" cellpadding="6">
                                                <tbody>
                                                    <tr>
                                                        <td width="100%" colspan="1" style="vertical-align: top;" >
                                                            <div style="text-align: right;">
                                                                <span class="ms-formlabel" style="border-top-width: 0px; 
                                                                    font-size: 12px; color: #ff0000; 
                                                                    padding-left: 28px;"
                                                                    title="Items with this symbol must have a value.">* Requires input</span>
                                                            </div>
                                                        </td>
                                                    </tr>
                                                </tbody>
                                            </table>
                                            <div style="color:#323232; padding-left: 10px; height: 37px; 
                                                background- top; background-repeat: repeat-x; 
                                                background-color: rgb(234, 243, 255); 
                                                background-image: url('/_layouts/images/MSILM2/homepage_shade_corporate.png') !important;">
                                                <table width="100%" border="0">
                                                    <tr>
                                                        <td style="margin-top: 6px; border-top-width: 0px; padding-top: 6px; text-align: right; vertical-align: top;">
                                                            <asp:button id="btnSubmit" runat="server" Text="Submit" 
                                                                style="color: #262626; border: solid 1px #707070; 
                                                                width: 88px; background-color: rgb(235, 235, 235); 
                                                                background-image: url('/_layouts/images/MSILM2/uocbutton_normal.png'); 
                                                                background-attachment: scroll; 
                                                                background- center; 
                                                                background-repeat: repeat;" 
                                                                OnClientClick="return btnSubmit_ClientClick(this);" 
                                                                onclick="Submit_Click" />&nbsp;
                                                            <asp:button id="btnCancel" runat="server" Text="Cancel" 
                                                                style="color: #262626; border: solid 1px #707070; 
                                                                width: 88px; background-color: rgb(235, 235, 235); 
                                                                background-image: url('/_layouts/images/MSILM2/uocbutton_normal.png'); 
                                                                background-attachment: scroll; 
                                                                background- center; 
                                                                background-repeat: repeat;" 
                                                                OnClientClick="window.close();" />&nbsp;
                                                        </td>
                                                    </tr>
                                                </table>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </span>
                        </span>
                    </td>
                </tr>
            </tbody>
        </table>
        </form>
    </body>
    </html>
    

    With a matched CodeBehind file in the same folder:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Reflection;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Text;
    
    using Microsoft.ResourceManagement.Client;
    using Microsoft.ResourceManagement.ObjectModel;
    using Microsoft.ResourceManagement.ObjectModel.ResourceTypes;
    
    namespace Custom.IdentityManagement.WebUI.LAYOUTS.Custom
    {
        public partial class JoinGroups : System.Web.UI.Page
        {
            #region Constants
            private const String _groupAttributeName = "ExplicitMember";
            private const String _updateAttributeName = "BusinessJustification";
            private const String _requestInfoLabelText = "Business Justification";
            private const String _requestInfoReasonLabelText = "Business reason for request?";
            private const String _requestInfoAllowLabelText = "What will this request allow you to do?";
            private const int _requestInfoMinLength = 5;
            #endregion
    
            #region Private Variables
            private String _businessJustification = String.Empty;
            private String _userAccountName = String.Empty;
            private String _userDomainName = String.Empty;
            private List<KeyValuePair<string,string>> Success = new List<KeyValuePair<string,string>>();
            private List<KeyValuePair<string,string>> Failed = new List<KeyValuePair<string,string>>();
            #endregion
    
            #region Public Properties
            public String BusinessJustification
            {
                get { return _businessJustification; }
                set { _businessJustification = String.IsNullOrEmpty(value) ? String.Empty : value.Trim(); }
            }
            public String UserFullName
            {
                set
                {
                    _userAccountName = String.Empty;
                    _userDomainName = String.Empty;
                    string[] splitName = value.Split(new string[] { @"\" }, 2, StringSplitOptions.RemoveEmptyEntries);
                    if (splitName.Length == 2)
                    {
                        this.UserAccountName = splitName[1];
                        this.UserDomainName = splitName[0];
                    }
                }
            }
            public String UserAccountName
            {
                get { return _userAccountName; }
                set { _userAccountName = value; }
            }
            public String UserDomainName
            {
                get { return _userDomainName; }
                set { _userDomainName = value; }
            }
            #endregion
    
            #region Methods
            protected void Page_Load(object sender, EventArgs e)
            {
                // Get name of the cache control value.
                NameValueCollection queryString = HttpUtility.ParseQueryString(Request.UrlReferrer.Query);
                String cacheID = queryString["CacheID"];
    
                this.lblInfoLabel.InnerHtml = _requestInfoLabelText;
                this.lblInfoReasonLabel.InnerHtml = _requestInfoReasonLabelText;
                this.lblInfoAllowLabel.InnerHtml = _requestInfoAllowLabelText;
    
                if (!String.IsNullOrEmpty(cacheID))
                {
                    // Get Identity objects from Page Cache.
                    Object obj = this.Page.Cache.Get(cacheID);
                    Assembly asm = obj.GetType().Assembly;
                    Type CachedObjectsWithIdentityType = obj.GetType();
                    PropertyInfo storedObjectsProperty = CachedObjectsWithIdentityType.GetProperty("StoredObjects");
                    Object storedObjects = storedObjectsProperty.GetValue(obj, null);
    
                    // Public properties of individual stored objects.
                    Type ObjectIdentityType = asm.GetType("Microsoft.IdentityManagement.ObjectIdentity");
                    PropertyInfo displayName = ObjectIdentityType.GetProperty("DisplayName");
                    PropertyInfo typeName = ObjectIdentityType.GetProperty("TypeName");
                    PropertyInfo id = ObjectIdentityType.GetProperty("Id");
    
                    // Create container for selected groups
                    this.ctrlGroups.Visible = true;
                    // Create list items for each group in cache.
                    IEnumerable storedEnumerable = storedObjects as IEnumerable;
                    foreach (Object objID in storedEnumerable)
                    {
                        if (objID.GetType() == ObjectIdentityType)
                        {
                            String DisplayName = (string)displayName.GetValue(objID, null);
                            String TypeName = (string)typeName.GetValue(objID, null);
                            Guid ID = (Guid)id.GetValue(objID, null);
                            ListItem group = new ListItem(DisplayName, ID.ToString());
                            this.ctrlGroups.Items.Add(group);
                        }
                    }
                    this.ctrlGroups.Rows = this.ctrlGroups.Items.Count + 1;
                }
            }
            protected override void CreateChildControls()
            {
                base.CreateChildControls();
            }
            private void ValidateItems()
            {
                if (!System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
                {
                    throw new Exception("You must be signed in to Join a Group.");
                }
                this.UserFullName = System.Web.HttpContext.Current.User.Identity.Name;
    
                if (this.ddlReason.SelectedValue.Length.Equals(0))
                {
                    throw new Exception(String.Format("'{0}' requires a selection.", _requestInfoReasonLabelText));
                }
    
                if (this.txtReason.Text.Trim().Length < _requestInfoMinLength)
                {
                    throw new Exception(String.Format("'{0}' cannot be empty and must meet {1} character minimum length requirement.", _requestInfoAllowLabelText, _requestInfoMinLength));
                }
    
                this.BusinessJustification = this.ddlReason.SelectedValue + ": " + this.txtReason.Text.Trim();
            }
            protected void Submit_Click(object sender, EventArgs e)
            {
                EnsureChildControls();
                try
                {
                    this.txtErrorText.Text = String.Empty;
                    this.trErrorRow.Style["display"] = "none";
    
                    // Validate required fields.
                    ValidateItems();
    
                    // Generate requests.
                    using (DefaultClient client = new DefaultClient())
                    {
                        this.Success.Clear();
                        this.Failed.Clear();
                        RmAttributeName explicitGroupAttributeName = new RmAttributeName(_groupAttributeName);
                        RmAttributeName justificationAttributeName = new RmAttributeName(_updateAttributeName);
                        RmReference user = GetCurrentUserReference(client, this.UserDomainName, this.UserAccountName);
                        foreach (ListItem group in ctrlGroups.Items)
                        {
                            foreach (RmResource rmResource in client.Enumerate("/Group[ObjectID='" + group.Value + "']"))
                            {
                                using (RmResourceChanges transaction = new RmResourceChanges(rmResource))
                                {
                                    transaction.BeginChanges();
                                    try
                                    {
                                        if (rmResource.Attributes.ContainsKey(explicitGroupAttributeName))
                                        {
                                            if (rmResource.Attributes[explicitGroupAttributeName].Values.Contains(user))
                                            {
                                                throw new Exception("You are already a member of this group.");
                                            }
                                            rmResource.Attributes[explicitGroupAttributeName].Values.Add(user);
                                        }
    
                                        if (rmResource.Attributes.ContainsKey(justificationAttributeName))
                                        {
                                            rmResource.Attributes[justificationAttributeName].Value = this.BusinessJustification;
                                        }
                                        else
                                        {
                                            rmResource.Attributes.Add(justificationAttributeName, new RmAttributeValueSingle(this.BusinessJustification));
                                        }
    
                                        try
                                        {
                                            client.Put(transaction);
                                            this.Success.Add(new KeyValuePair<string, string>(rmResource.DisplayName, "Added membership."));
                                        }
                                        catch (System.ServiceModel.FaultException ex)
                                        {
                                            if (ex.Message.Equals("Permission is required", StringComparison.InvariantCultureIgnoreCase))
                                            {
                                                this.Success.Add(new KeyValuePair<string, string>(rmResource.DisplayName, "Pending approval."));
                                            }
                                            else
                                            {
                                                throw new Exception("Authorization failed.");
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        this.Failed.Add(new KeyValuePair<string, string>(rmResource.DisplayName, ex.Message));
                                    }
                                }
                                break;
                            }
                        }
                    }
    
                    // Close window if all requested submits processed successfully.
                    if (this.Failed.Count == 0)
                    {
                        Page.ClientScript.RegisterStartupScript(this.GetType(), new Guid().ToString(), "<script type=text/javascript> window.opener=self; window.close();</script>");
                    }
                    else
                    {
                        // Display any errors or status messages.
                        this.btnSubmit.Enabled = false;
                        this.txtReason.Enabled = false;
                        if (this.Success.Count > 0)
                        {
                            foreach (KeyValuePair<string, string> item in this.Success)
                            {
                                TableRow newRow = new TableRow();
                                TableCell newGroup = new TableCell();
                                TableCell newStatus = new TableCell();
                                newGroup.Text = item.Key;
                                newGroup.Style.Add("border", "solid 1px black");
                                newStatus.Text = item.Value;
                                newStatus.Style.Add("border", "solid 1px black");
                                newRow.Cells.Add(newGroup);
                                newRow.Cells.Add(newStatus);
                                this.tblSuccess.Rows.Add(newRow);
                            }
                        }
                        else
                        {
                            TableRow newRow = new TableRow();
                            TableCell newMessage = new TableCell();
                            newMessage.ColumnSpan = 2;
                            newMessage.Text = "No group memberships have been submitted.";
                            newMessage.Style.Add("border", "solid 1px black");
                            newRow.Cells.Add(newMessage);
                            this.tblSuccess.Rows.Add(newRow);
                        }
    
                        foreach (KeyValuePair<string, string> item in this.Failed)
                        {
                            TableRow newRow = new TableRow();
                            TableCell newGroup = new TableCell();
                            TableCell newStatus = new TableCell();
                            newGroup.Text = item.Key;
                            newGroup.Style.Add("border", "solid 1px black");
                            newStatus.Text = item.Value;
                            newStatus.Style.Add("color", "Red");
                            newStatus.Style.Add("border", "solid 1px black");
                            newRow.Cells.Add(newGroup);
                            newRow.Cells.Add(newStatus);
                            this.tblFail.Rows.Add(newRow);
                        }
                        this.StatusTable.Visible = true;
                    }
                }
                catch (Exception ex)
                {
                    // Display Error message.
                    this.txtErrorText.Text = ex.Message;
                    this.trErrorRow.Style["display"] = "table-row";
                }
            }
            private RmReference GetCurrentUserReference(DefaultClient client, string domainName, string userName)
            {
                foreach (RmResource personRes in client.Enumerate(string.Format("/Person[(Domain='{0}') and (AccountName='{1}')]", domainName, userName)))
                {
                    RmPerson person = personRes as RmPerson;
                    if (person != null)
                    {
                        return person.ObjectID;
                    }
                }
                throw new Exception(String.Format(@"{0}\{1} is not a valid user.", domainName, userName));
            }
            #endregion
        }
    }
    

    Hope this helps,



    • Proposed as answer by sylguyot Monday, January 14, 2013 10:02 AM
    Thursday, January 10, 2013 6:05 PM
  • Thank you very much!!

    Do you have the same for the AddMembers.aspx page : i would like to authorize admin to add only one member in the Members picker??

    Regards,

    • Edited by sylguyot Monday, January 14, 2013 10:13 AM
    Monday, January 14, 2013 9:52 AM
  • The problem with the AddMembers.aspx page is that the UocIdentityPicker control is an Internal control, only visible to Microsoft's assemblies. This means you cannot use it on a custom .aspx page. The .aspx page, if using a CodeBehind file for supporting changes without compiling, requires that you write everything to be ASP.Net 2.0 compilable. You cannot use any of the 3.0/3.5 enhancements and extension libraries. The replacement page I came up with has a 1300 line codebehind file, which instantiates a few custom developed controls (like a replacement for the Resource Picker and search governor to cancel runaway queries). These controls are in other GAC'd utility assemblies, but the codebehind file must handle all of the postback events. The JoinGroups replacement is rather simple compared to the way AddMembers must be made.

    If I posted the contents of the AddMembers page, it would not be very helpful or a functional solution without you writing a lot of custom controls.

    Regards,

    Monday, January 14, 2013 1:39 PM
  • Wednesday, January 16, 2013 11:29 AM