Thursday, July 22, 2010

Impersonation in ASP.NET causes [COM.Exception(0x80072020) : An Operations error occurred.]

When you run code that uses DirectorySearcher, DirectoryEntry or other classes that communicates with network resources from a webpart in a Sharepoint site, you recieve a: [COMException (0x80072020): An operations error occurred. ]
This is caused by the fact that when a user is authenticated against a sharepoint server using NTLM or Kerberos, a "secondary token" is sent to the server that it uses to authenticate the user. This token cannot be used to authenticate the current user against another server (e.g. a domain controller).
This can be circumvented by reverting the impersonation to the application pool account used by IIS (if this account has access to Active Directory) with the following code (this is equal to running with impersonation set to false in web.config):

C#:

using System.Web.Hosting;
...
...
// Code here runs as the logged on user
using (HostingEnvironment.Impersonate()) {// This code runs as the application pool user
     DirectorySearcher searcher ...
}

// Code here runs as logged on user again 

VB:

// Code here runs as the logged on user
Using (System.Web.Hosting.HostingEnvironment.Impersonate())

// This code runs as the application pool user
     DirectorySearcher searcher ...
 

End Using

// Code here runs as logged on user again

Monday, June 21, 2010

Writing Messages to Event Log in SharePoint

In SharePoint using System.Diagnostics.EventLog class, you can write messages to event log.
Below is the code snippet for the same,

string source = "Demo Application";
if (!EventLog.SourceExists(source))
EventLog.CreateEventSource(source, "Application");
EventLog.WriteEntry(source, "Message!", EventLogEntryType.Error);

Thursday, June 17, 2010

Custom aspx pages in SharePoint 2010

While migrating Custom aspx pages from MOSS 2007 to SP 2010, below mentioned pages directives are to be modified accordingly.

MOSS way of doing
<%@ Page Language="C#" Inherits="Microsoft.SharePoint.ApplicationPages.NewListPage" MasterPageFile="~/_layouts/application_Custom.master" %>

SP 2010 way of declaring the directive,

<%@ Page language="C#"
 MasterPageFile="~/_layouts/application_Custom.master"
 Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c"%>

If the page inherits publishing layouts page, the directive should be modified as shown below,

MOSS way of doing:
<%@ Page Language="C#" DynamicMasterPageFile="~masterurl/default.master" Inherits="Microsoft.SharePoint.Publishing.Internal.CodeBehind.CategoriesPage"%>

SP 2010 way of doing: 

Follow the below two steps to apply master page here. MasterPageFile tag is not supported directly.

1. <%@ Page Language="C#" Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage,Microsoft.SharePoint,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c"%> 

2. And, then under script tag, override "OnPreInit" method & assign master page there.
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
this.MasterPageFile = "SomeOther.master";
}

Monday, June 14, 2010

Copy attachments from one list item to another within a SharePoint site

Attachments for a list item are stored as SPFile objects under a hidden folder in the list where those attachments are stored. Each list item that has an attachment has its own folder with the ID of the item being the folder's name. Here is a code sample to copy attachments from one item to another:

private void CopyAttachments(SPWeb oSPWeb, SPListItem sourceItem, SPListItem targetItem)
{
//get the folder with the attachments for the source item
 
SPFolder sourceItemAttachmentsFolder =      
 sourceItem.Web.Folders["Lists"].SubFolders[sourceItem.ParentList.Title]
.SubFolders["Attachments"].SubFolders[sourceItem.ID.ToString()];

//Loop over the attachments, and add them to the target item
 
foreach (SPFile file in sourceItemAttachmentsFolder.Files)
 {
   byte[] binFile = file.OpenBinary();
   oSPWeb.AllowUnsafeUpdates=true;
   targetItem.Attachments.AddNow(file.Name, binFile);
   oSPWeb.AllowUnsafeUpdates=false;
 }
}

Friday, June 4, 2010

SharePoint people picker is not able to resolve names from different forests / domains

Some time back, I was caught into this issue after upgrading MOSS from SP1 to SP2. People Picker wasn't able to resolve users from different forests / domains.

After struggling for plenty of hours, I got the solution. Actually when you have to fetch users from different forests or domains, you should have user id & password detail of that specific domain with read access to directory services of that AD.

Execute the below mentioned command to edit property of people picker so that it can search cross forest / domain users.

Step 1. stsadm -o setapppassword -password key
Step 2. stsadm -o setproperty -url "http://portal_URL" -pn peoplepicker-searchadforests -pv "forest:FQFN;domain:FQDN",LoginID,Password


Step 1= Encrypts the password
Step 2= sets property of people picker.

a. portal_URL = Specify your portal / application URL
b. FQFN = Fully Qualified Forest Name
c. FQDN = Fully Qualified Domain Name
d. Login ID = Specify Login ID as (Domain Name\xyz)
e. Password = Specify password for the login. If password contains any special character, provide the password details in double chords. e.g "Hello,11"

If you have to add multiple forests / domains to people picker, you may have to execute below mentioned command for the same.

Step 1: stsadm -o setapppassword -password key
Step 2. stsadm -o setproperty -url "http://portal_URL" -pn peoplepicker-searchadforests -pv "forest:FQFN1;domain:FQDN1",LoginID1,Password1;"forest:FQFN2;
domain:FQDN2",LoginID2,Password2


As shown above, you can add multiple domains in single command line.

FQFN1, FQDN1, LoginID1, Password1 = details for first forest / domain
FQFN2, FQDN2, LoginID2, Password2 = details for second forest / domain

Note: Login IDs should atleast have read access to directory services of respective ADs.

Hope this may help you. Happy Blogging !!!

Thursday, May 27, 2010

Stsadm to Windows PowerShell mapping (SharePoint Server 2010)

Microsoft has published a very useful new article on Technet that lists STSADM operations and their equivalent PowerShell cmdlets. Check this link.

Thursday, May 13, 2010

Disable event firing in sharepoint when updating list item

Below piece of code can be used to update SharePoint list item inside any event receiver. I have written it for Updated event receiver.


public override void ItemUpdated(SPItemEventProperties properties)

{

//some handling here

ListItem item = properties.ListItem;

item["someproperty"] = "some value";

this.DisableEventFiring();

//save changes added

Item.Update();

this.EnableEventFiring();

}