Welcome to MSDN Blogs Sign in | Join | Help

How are SSP Associations Changed?

I recently heard a question, “How do you change SSP web application associations through the object model (OM)?”  Searching the OM online help didn’t find any results. Any yet theoretically, it must be possible, since you can set the web application SSP association through Central Administration.

Then the thought occurred, why not reverse engineer the Central Administration page to see how it is done? Here are the steps. This technique can be applied to any administration page if you are curious how the product team wrote the code.

Step 1: Download and install Lutz Roeder’s .NET Reflector (http://www.aisto.com/roeder/dotnet/Download.aspx?File=Reflector), if you don’t already have it. This is an essential tool for any serious .NET developer.

Step 2: Navigate to the page where the operation is performed. In this example, the page is the Change Associate between Web Applications and SSPs -- Central Administration > Application Management > Manage this Farm's Shared Services > Change Association between Web Applications and SSPs. Note the aspx file name in the URL: http://litwareserver:9999/_admin/changewebappassociation.aspx.

Step 3: Use Windows Explorer to locate the page on the file system.

Locating PageStep 4: Open the page with a text edit like NotePad. Find the base class name and assembly in the page directives. In this example we are interested in the ChangeWebAppAssociationPage located in the Microsoft.Office.Server.UI assembly.

<%@ Page Language="C#" Inherits="Microsoft.Office.Server.Internal.UI.ChangeWebAppAssociationPage,`fa,Version=12.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" MasterPageFile="admin.master"      %>

<%@ Register Tagprefix="wssawc" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

Step 5: Open the assembly with .NET Reflector. This can be tricky. Code-behind classes of pages in the LAYOUTS directory are frequently in Microsoft.SharePoint.ApplicationPages.dll found in the _app_bin folder of the web application; but we don’t see Microsoft.Office.Server.UI.dll there. The next logical place to look is in the GAC. Here we do find the assembly, but Reflector can’t directly open assemblies from the GAC.

We have to make a copy of the assembly in another location on the disk. Open a command prompt, and then navigate to the directory:

C:\WINDOWS\assembly\GAC_MSIL\Microsoft.Office.Server.UI\12.0.0.0__71e9bce111e9429c Next copy the assembly to a disk location; such as, c:\temp:

>copy Microsoft.Officer.Server.UI.dll c:\temp.

You can now open the assembly with Reflector from the disk location.

Step 6: Open the code-behind class, locate the on-click event handler for the page submit button and select Disassemble from the context menu.

 Disassembling class

Review the code to see how the object model is used to update the farm configuration. The disassembled code may appear convoluted at first. It will contain labels and goto’s, rather than foreach and while, but with a little study it will make sense.

protected void OkButtonClick(object sender, EventArgs e)

{

    string str;

    SharedResourceProvider selectedSsp = base.GetSelectedSsp(this.SharedServicesProviderDropDown);

    SharedResourceProviderCollection providers = new SharedResourceProviderCollection(SPFarm.Local);

    SPWebApplicationCollection applications = new SPWebApplicationCollection(SPFarm.Local.Services.GetValue<SPWebService>(string.Empty));

    uint num = 0;

    uint num2 = 0;

    IEnumerator enumerator = this.WebApplicationsGridView.Rows.GetEnumerator();

    try

    {

        SPGridViewRow row;

        DataControlFieldCell cell;

    Label_00A4:

        if (enumerator.MoveNext())

        {

            goto Label_00EB;

        }

        if (((selectedSsp == null) || (base.ParentSsp == null)) || !(selectedSsp.Id == base.ParentSsp.Id))

        {

            goto Label_004E;

        }

        goto Label_014C;

    Label_00B2:

        cell = (DataControlFieldCell) row.Controls[1];

        SPWebApplication application = applications.GetValue<SPWebApplication>(SPHttpUtility.HtmlDecode(cell.Text));

        providers[application] = selectedSsp;

        num2++;

        goto Label_00A4;

    Label_00EB:

        row = (SPGridViewRow) enumerator.Current;

        CheckBox box = (CheckBox) row.Controls[0].Controls[1];

        if (!box.Enabled || !box.Checked)

        {

            goto Label_00A4;

        }

        goto Label_00B2;

    }

    finally

    {

        IDisposable disposable = enumerator as IDisposable;

        if (disposable != null)

        {

            disposable.Dispose();

        }

    }

    goto Label_014C;

Label_004E:

    str = base.Request.QueryString["asChild"];

    if ((str == null) || !str.Equals("true", StringComparison.OrdinalIgnoreCase))

    {

        SPUtility.Redirect("/_admin/managessp.aspx", SPRedirectFlags.Static, this.Context);

        return;

    }

    SPUtility.Redirect("/_admin/information.aspx?internal=child", SPRedirectFlags.Static, this.Context);

    return;

Label_014C:

    SQM.AddTo1WideStream(SQMDP.DATAID_OSSIFSSCOUNTOFWEBAPPS, num2 + (num << 0x10));

    goto Label_004E;

}

 

The answer to the original question is that the SSP is configured by setting a property on the WebApplication object. If we were to follow the method calls from the above code, we eventually arrive at these statements:

    webApplication.Properties["Microsoft.Office.Server.SharedResourceProvider"] = srp;

    webApplication.Properties["Microsoft.Office.Server.IsParentSharedResourceProvider"] = flag;

    webApplication.Update();

The next logical question is, can we use, duplicate, or override the code we find in Reflector? The answer depends upon the access modifiers. If the class is marked as private or internal, you are out of luck – the method or property cannot be accessed from custom code. If the class is public, but sealed, then you cannot subclass it. If we drilldown into the SPWebApplication class, we find these properties and methods are public, so we should be able to call and/or override. This is left as an exercise for the reader.

Published Sunday, April 20, 2008 8:14 AM by jimmiet
Filed under:

Comments

# How are SSP Associations Changed?

Sunday, April 20, 2008 9:36 AM by Jimmie's Sharings

I recently heard a question, “How do you change SSP web application associations through the object model

Anonymous comments are disabled
 
Page view tracker