All posts by Ayman El-Hattab [MVP]

Ayman El-Hattab is a Technology Evangelist @ Nintex & a recognized industry expert focusing on helping organizations plan, design, develop, build, govern and operate enterprise collaboration solutions. You can follow Ayman on Twitter @AymanElHattab to stay updated on his upcoming activities.

Be Careful When Using properties & SPContext

What is SPContext ?
In a nutshell, SPContext object can be used to get a reference to the site or the web from the current context, It Represents the context of an HTTP request in SharePoint .
For instance :
SPList currentList = SPContext.Current.List;
SPWeb currentSite = SPContext.Current.Web;
SPSite currentSiteCollection = SPContext.Current.Site;
SPWebApplication currentWebApplication = SPContext.Current.Site.WebApplication;
SPListItem item = (SPListItem)SPContext.Current.Item;
SPUser user = SPContext.Current.Web.CurrentUser;

What is “Properties” ?
The properties object holds information about an event. You can use it to get references to SPSite, SPWeb, SPList or SPList Item.
for instance :
SPListItem item = properties.ListItem’

However,
Be VERY careful when using properties parameter or SPContext. You CANNOT use the properties command to create your objects or your code will fail! .
You need to use properties or SPContext to locate the items, then use the items IDs to create the object references. You will never get your code to work the way it is above.
You need to get all of the Guid identifiers BEFORE entering the secure block ( RunWithElevatedPriveleges) or Impersonation, then create all the objects you need WITHIN the secure context

Guid SiteId = SPContext.Current.Site.ID;
Guid WebId = SPContext.Current.Web.ID;
Guid ListId = properties.ListId;
Guid UniqueId = properties.ListItem.UniqueId;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site= new SPSite(SiteId))
{
using (SPWeb web= site.AllWebs[WebId])
{
SPList list= web.Lists[ListId];
SPListItem listItem= list.Items[UniqueId];
// Code..
}
}
});

or to impersonate the system account using SPUserToken ( Recommended )

Guid SiteId = SPContext.Current.Site.ID;
Guid WebId = SPContext.Current.Web.ID;
Guid ListId = properties.ListId;
Guid UniqueId = properties.ListItem.UniqueId;
SPUserToken systemAccountToken = SPContext.Current.Site.SystemAccount.UserToken;
using(SPSite mySite = new SPSite(SiteId, systemAccountToken))
{
using (SPWeb myWeb = mySite.OpenWeb(WebId))
{
SPList list= web.Lists[ListId];
SPListItem listItem= list.Items[UniqueId];
// Code..
}
}

Advertisements

Where EXACTLY are they stored ?!!!

I used to ask myself , Where exactly are sharepoint documents stored ?
hmm may be on the file system ? no ! Not reasonable..
In the content database ? hmm
After investigating this subject, I found out that every time you save a document in the document library on a SharePoint site, the entire contents of the document is saved in binary format in a single image-type field in the SharePoint database.
WOW, an entire document in a single field ??

When I told a colleague about that he asked me for an evidence.
Ok !

Guys, check this link : http://msdn.microsoft.com/en-us/library/ms998690.aspx , documentation on the Microsoft Developer Network always says the truth 🙂

SPUserToken, The Hero !

A few days ago, I wrote event handler code that runs in the security context of the logged in user. SharePoint security model makes it easy to programmatically execute code within the current user context But there were some situations when the code needs to be executed with permissions greater than that of the current user (like instantiating a site collection or enumerating list permissions ).

In such situations, the code needs to be executed with elevated permission level or under the context of user with higher permissions i.e. Impersonation.
As the MSDN documentation says, SPSecurity.RunWithElevatedPrivelege “Executes the specified method with Full Control rights even if the user does not otherwise have Full Control.”
In my experience with Using SPSecurity.RunWithElevatedPrieveleges, there are too much tricks that you should take care of.
For Instance : You must create the new SPSite objects inside the delegate because SPSite objects created outside do not have Full Control even when referenced inside the delegate. Use the using keyword to ensure that the object is disposed in the delegate. The next example shows this. SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(web.Site.ID))
{ // Perform elevated actions here
}
});
The problem is that the SPWeb object from the current context is initialized using the current user’s credentials, so even though we run the code snippet with elevated privileges the actual access to the file is still restricted. To resolve this we have to create a new SPSite/SPWeb object within the elevated code, where we run in the context of the elevated user. Then we can perform the restricted action. Since the SPSite/SPWeb objects are created explicitly we have to also dispose of them.
There’s too much overhead, too much chances of introducing obscure bugs, too much potential abuse when it comes to using SPSecurity.RunWithElevatedPrievelges.

That’s why I’d recommend to use SPUserToken to impersonate the SYSTEM and use elevated privileges.

Fortunately, the SystemAccount SPUser is a property of any SPSite object. So instead of using SPSecurity.RunWithElevatedPrivelege, you can use the following code to perform elevated actions:

SPUserToken systemAccountToken = SPContext.Current.Site.SystemAccount.UserToken;
using(SPSite mySite = new SPSite(SPContext.Current.Site.ID, systemAccountToken))
{
using (SPWeb myWeb = mySite.OpenWeb(SPContext.Current.Web.ID))
{
// Perform elevated actions here
}
}

The Evils of AllWebs !

As I have been working to develop an event handler that will be used to mirror a Document Library, I’ve come across an interesting tid bit that was frustrating at first.

It’s worth mentioning that in MOSS 2007, Event Handlers execute in the context of the current user rather than the process user in SharePoint 2003 .

The event handler contained the following piece of code :
using( SPWeb web = SPContext.Current.Site.AllWebs[guid] )
{
// code
}

When running as an administrator, the event handler worked fine. However, if you switch to a non-administrative user that doesn’t have full control of the site, you’ll get a lovely exception. The problem is that you must have full control of the site to be able to use the AllWebs property.

To solve this, try the following code:

using( SPWeb web = SPContext.Current.Site.OpenWeb(guid) )
{
// code
}

Happy SharePoint Coding 😀

Multiple Document Upload issue in MOSS 2007

I recently had an issue when trying to upload multiple documents to SharePoint 2007 Document Library . I receive the following error :” Cannot run Windows SharePoint Services on this page” .

To fix this issue :

1) Go to the Central Administration from Start > Microsoft Office Server à SharePoint Central Administration
2) Choose the Application Management tab
3) Choose Authentication providers from Application Security
4) Change the web Application to your web application then select the zone that failed ( Mine was Default )
5) Disable the client integration by selecting No
6) Return to the default zone again
7) Enable the client integration by choosing “Yes”
8) Now you can use the multiple upload feature
18
19

Create KPIs Programmatically in PerformancePoint 2007

I created this web project while I was investigating the performancepoint API, it was really a very hard and silly task so I decided to share this code with you 🙂

Firstly, Add a reference to :
\Microsoft Office PerformancePoint Server\3.0\Monitoring\Assemblies\Microsoft.PerformancePoint.Scorecards.Common.dll

using Microsoft.PerformancePoint.Scorecards;
using System.Net;

public partial class _Default : System.Web.UI.Page
{
private Kpi kpi_wows;
private PmService Publisher;

protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Publisher = (PmService)PmService.CreateInstance(“http://localhost:40000/webservice/pmservice.asmx”);
Publisher.Credentials = CredentialCache.DefaultNetworkCredentials;

}
protected void Page_Load(object sender, EventArgs e)
{
CreateKPIandSetSomeProperties();
}

private void CreateKPIandSetSomeProperties()
{
// Create a new kpi instance
kpi_wows = Kpi.CreateNew();
// Setting its name
kpi_wows.Name.Text = “zzz”;
// Setting the Owner
BpmPropertyUser Owner = new BpmPropertyUser();
Owner.Login = @”Server\Administrator”;
kpi_wows.Owner = Owner;
// setting the actual
KpiMeasure ActualMeasure = new KpiMeasure();
ActualMeasure.Guid = Guid.NewGuid();
ActualMeasure.ModelCurrent = 345M;
BpmPropertyText ActualName = new BpmPropertyText();
ActualName.Text = “The Actual”;
ActualMeasure.Name = ActualName;
ActualMeasure.ValueSource = ValueSources.MaxRollup;
kpi_wows.Actual = ActualMeasure;
// Setting the Target
Target ATarget = new Target();
ATarget.Guid = Guid.NewGuid();
ATarget.ModelCurrent = 656M;
BpmPropertyText TargetName = new BpmPropertyText();
TargetName.Text = “The Target”;
ATarget.Name = TargetName;
// Scoring Pattern
ATarget.Pattern = KpiPattern.DecreasingIsBetter;
// Banding Method
Banding TargetBanding = new Banding();
TargetBanding.Type = BandType.Normalized;
TargetBanding.ActualWorst = 999M;
TargetBanding.SpreadMinimum = 0M;
TargetBanding.SpreadMaximum = 1.2M;
TargetBanding.CustomBoundary.Add(0.1M);
TargetBanding.CustomBoundary.Add(0.2M);
ATarget.Banding = TargetBanding;
ATarget.IndicatorId = new Guid(“70b22c72-6523-487d-ae4a-ad607431584f”);
ATarget.IsCustomCurrentFormula = true; // If true, then CurrentFormula is used to compute the current value.
//ATarget.CurrentFormula = “————–MDX Formula Goes Here ————-“;
ATarget.CurrentFormula = “0”;
kpi_wows.Targets.Add(ATarget);
//Adding Description
kpi_wows.Description.Text = “This is a kpi created by the object model”;
// Assigning Permissions
Microsoft.PerformancePoint.Scorecards.Membership AdministratorMembership = new Microsoft.PerformancePoint.Scorecards.Membership();
AdministratorMembership.Login = @”Server\Administrator”;
AdministratorMembership.Role = “Editor”;
Microsoft.PerformancePoint.Scorecards.Membership ReaderMembership = new Microsoft.PerformancePoint.Scorecards.Membership();
ReaderMembership.Login = @”Server\ayman_elhattab”;
ReaderMembership.Role = “Reader”;
kpi_wows.Memberships.Add(AdministratorMembership);
kpi_wows.Memberships.Add(ReaderMembership);
// Assigning the Responsible Person
kpi_wows.Owner.Login = @”Server\Administrator”;

// publishing the KPI
Publisher.CreateKpi(kpi_wows);
}

}