Archive Page 2

Sharepoint SPGridView control is expanded by default

The Sharepoint SPGridView control seems to be rendered as expanded sometimes, although it should be collapsed.

Here is a javascript function to fix this issue:

function spGridViewFixExpandedGroups(gridviewId) {
    var gridview = $("[id$='" + gridviewId + "']");
    var links = gridview.find("tr[isexp='true'] a[title='Expand/Collapse']");
    links.click();
}

Simply call the script upon page load. Note: The script requires the jQuery library to be included.

Disable Sharepoint item events firing during item update

In Sharepoint, the attached item events are fired whenever you perform an item.Update()
Ryan posted a solution to this issue, using a custom event handler that disables the events upon request.

What I dislike about the solution, is the risk of leaving the events disabled. Assume an exception occurs, the code will never reach the line where the event firing is enabled (restored) again.

I suggest a using-pattern, much like the TransactionScope class used for db transactions in the entity framework.

    class DisabledItemEventsScope : SPItemEventReceiver, IDisposable
    {
        public DisabledItemEventsScope()
        {
            base.DisableEventFiring();
        }

        #region IDisposable Members

        public void Dispose()
        {
            base.EnableEventFiring();
        }

        #endregion
    }

Now we can use this class together with the using syntax to create a scope within all item event firing is disabled.

                using (DisabledItemEventsScope scope = new DisabledItemEventsScope())
                {
                    item.SystemUpdate(); // will NOT fire events
                }
                item.SystemUpdate(); // will fire events again

This way, the event firing is enabled again as soon as the code leaves the defined scope, be it through normal operation or by exceptions.

Update 1

For SharePoint 2010, use this snippet instead:

    /// <summary>
    /// Disabled item events scope
    /// </summary>
    /// <see cref="https://adrianhenke.wordpress.com/2010/01/29/disable-item-events-firing-during-item-update/"/>
    class DisabledItemEventsScope : SPItemEventReceiver, IDisposable
    {
        bool oldValue;

        public DisabledItemEventsScope()
        {
            this.oldValue = base.EventFiringEnabled;
            base.EventFiringEnabled = false;
        }

        #region IDisposable Members

        public void Dispose()
        {
            base.EventFiringEnabled = oldValue;
        }

        #endregion
    }

Outlook contacts: Move all numbers from “Other Phone” to “Mobile Phone” field

Outlook contact items have multiple available fields for storing phone numbers. Such as “other phone” and “mobile phone”.

Unfortunately some mobile phone sync software stores the numbers in the “other phone” fied, which becomes a problem if you switch to a new mobile phone that is not able to read this field. I wrote this little powershell script to scan all outlook contacts and migrate the values from the “other phone” field to the “mobile phone” field:

$outlook = new-object -com outlook.application
$contacts = $outlook.Session.GetDefaultFolder(10)
$contacts.Items | % { if($_.MobileTelephoneNumber -eq "") { $_.MobileTelephoneNumber = $_.OtherTelephoneNumber; $_.OtherTelephoneNumber = ""; $_.save() } }

Copy&paste the above source code into your PowerShell window to run it.

Sharepoint Designer, changing list forms does not work

In Sharepoint Designer, you can specify the path to the display item form, edit item form and new item form. You find these settings in the list properties under “supporting files”.

However sometimes sharepoint silently discards your changes and uses the original form again. No matter how often you specify your custom form, it will be changed back to the original form. If this happens to you, try the following:

  • Make sure your form contains the original ListFormWebPart, set its IsIncluded property to false.
  • Open your form in design view and make sure that none of the components (like custom webparts) throw an exception during rendering

If sharepoint encounters one of the issues above, it might reset the supporting files url back to the original values. Let me know if there are more conditions that cause this issue..

Sharepoint InternalName vs. DisplayName

This blogpost describes the internalname vs. displayname problem in the Sharepoint object model, nice to know…

The request failed with HTTP status 401: Unauthorized in Report Services 2008 Sharepoint Integration

Today I tried to integrate Reporting Services and Sharepoint. The setup consisted of three servers:

  • SQL 2008
  • Reporting Services 2008
  • Sharepoint (WSS 3.0) with Reporting Services Addins

When I tried to connect Sharepoint to the Reporting Services Webservice using the Central Administration, I got the following error:

The request failed with HTTP status 401: Unauthorized

However when I manually visited the webservice through the browser @ http://myserver/ReportServer, everything worked fine. So why did the authentication fail for Sharepoint?

My Sharepoint setup uses NTLM authentication only, therefore Reporting Services must be configured for the same authentication type as well. After reading through tons of KB articles and posts, i finally found a solution to the problem:

  1. On the Reporting Services Server, open the config file rsreportserver.config (you find it in the Reporting Services folder)
  2. Look for the Autentication configuration node
  3. Remove the RSWindowsNegotiate setting

The config section in question should now look like this:

<Authentication>
  <AuthenticationTypes>
    <!-- <RSWindowsNegotiate/> -->
    <RSWindowsNTLM/>
  </AuthenticationTypes>
  <EnableAuthPersistence>true</EnableAuthPersistence>
</Autentication>

That way, only NTLM is used for authentication. This fixed it for me 🙂

Add existing users to Sharepoint in “Active Directory Account Creation Mode”

If you run a WSS 3.0 Farm in the so called Active Directory Account Creation Mode you can not add existing users to your site collection. You are restricted to users that were created in the respective site collection.

To work around this limitation, you can abuse the stsadm utility to publish an existing user into a site collection:

  1. Log in to your portal and create a new user, name it “dummy” with a non-existing E-Mail address like dummy@dummy.local
  2. On your Webserver, start a command prompt and navigate to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\Bin
  3. From there, run the STSADM utilty:
stsadm.exe -o migrateuser -oldlogin MYDOMAIN\dummy -newlogin MYDOMAIN\myExistingUser -ignoresidhistory

This will replace all Sharepoint-internal references to the dummy user by references your existing user. That way your existing user is visible in the isolated site collection.

Some notes about this techniques:

  • User attributes such as E-Mail, Title, Position, etc will not be updated along with the user SID.
  • If a user called dummy already existed, Sharepoint will create a User like dummy1 instead. I suggest you take a look at the dummy users creation date in Active Directory before issuing the stadm command.
  • Delete the dummy user after the migration.
  • The user references are being updated in the whole Sharepoint Farm.
  • If you dont specify -ignoresidhistory, the SID histories of both users will be compared for matches. And if there are no matches, the operation will fail.