Monday, December 28, 2009

STSADM AddSolution failed to extract the cab file in the solution

Title: Error: Stsadm AddSolution failed to extract the cab file in the solution

Details: When tried to addsolution using stsadm command, some times the above error is experienced. Now, what to look for?

Steps:
Step#1: Extract your .wsp file
Step#2: Check the contents and make sure there are no duplicates ( files or resources )
Step#3: See if you have any files with special characters including brackets ' copy (2) filename ' so on and so forth.
Step#4: Clean up unwanted files and rebuild your .wsp.
Step#5: Addsolution this time and verify.

You should be good now.

The query results cannot be enumerated more than once

Title: Error: The query results cannot be enumerated more than once

Details: Ever tried using Linq DataContext model ( using the dbml file ) and try iterating from the return type ISingleResult ? If so, you might have got the error for sure. So, the simple way to do it is to obtain the results to a generic list as shown below.

Code: Consider that GetUserDetails returns a ISingleResult generic list type of GetUserDetailsResult

List<GetUserDetailsResult> results = GetUserDetails().ToList();
foreach (GetUserDetailsResult result in results)
{
// Write your code here...
}

Friday, December 25, 2009

SharePoint 2010 Sandboxed Solutions

Title: SharePoint 2010 Sandboxed Solutions

Introduction: How many times ( as a developer ) have you felt you wanted to have control on testing, staging or productions servers to deploy your solution? and how many times you might have bothered your engineering team for deployment? Similarly, how many times the engineering team might have cursed you for going to them many times to redeploy your solutions? Sounds familiar situation? Well with the introduction of Sandboxed Solutions, its a great relief to both the teams. Lets see in short in the post and I will write separately on each topic in other posts.

Sandboxed Solutions: With elevated previlages ( site collection administrators ), now you can deploy your solutions (.wsp) at the site collection level and fully control them. So, all you need is to request your engineering groups to add you to the Site collection administrators group on the target site collection. With SB Solutions, one can guarentee trust (partial) as well as protection to the farm. Since the SBS's work on a site collection, if any thing goes wrong only that site collection is compromised and would isolate the other Site collections, Web Application as well as Farm. SBS works on a different thread (SPUCWorkerProcess) and doesnt run on the same app pool. This isolation guarentees further more safety.

Build - Deploy: With VS 2010 one can opt for creating a SB Solution Project (default). However when the same solution is deployed at Farm Level, it runs with full trust where as at the site collection level it runs under partial trust. The output of the VS project would be a .wsp which you can upload to the Solutions store under the site collection. You can as well directly use the deploy option of VS however it may not be a suitable for staging and production deployments. You would simple Activate it ( equivalent to deploying the .wsp ) to run your underneath resources. When you donot need it, simply De-Activate the same.

Limitations: You cannot acheive everything using SBS's. As mentioned earlier since its partially trusted donot assume you can attempt to write everything using SBS. Here is list of ( some of ) what you can create

  • Web Parts ( not visual webparts )

  • Site Pages ( not application pages with code behind )

  • List Definitions

  • Event and Feature receivers

  • Infopath form services

  • Custom Actions

  • Content Type and Site Columns

  • JS, AJAX, SilverLight, jQuery ...



Monitoring and Validating: Farm Admins can monitor using the site quota's under CA and specify locks. Alternatively, using SPSolutionValidator Farm admins can monitor and validate the solutions that allow only code signed with a particular certificate to run.

Monday, December 21, 2009

Installing SharePoint 2010 Beta

Title: Installing SharePoint 2010 Beta

Preface: I failed trying to install SharePoint 2010 Beta more than 8 times and finally I was able to do it today. Here is what I did so far and finally what worked out. Installing it on a Windows 7 or Vista OS targetting developer user is no brainer. Simply follow this link and I was able to do it first time. However, my motto is to install it on a Virtual Machine ( VMWare ). So, I started with VMWare 7.0 with 4 core, 4GB RAM, 60GB HDD etc to begin with. I tried to install on both Windows Server 2008 Ent x64 and Windows Server 2008 R2 x64 versions. And when ever I tried to install with pre requisite setup etc, never been successful. Below are few errors I faced ( not all included ).

Errors:
#1 Application Server Role: Web Server (IIS) Role: configuration error
#2 pending restart of the computer.

References: Though I was unsuccesful installing it, these are great resources to follow and give ultimate information.
Sahil Malik's Blog
Jie Li's Blog
Code Project
Patrick's Blog

Finally: I went back to basics... ( my VM settings are same as mentioned above, no changes )
Step #1 Installed Windows 2008 Server 'Standard' Edition and ran the windows updates ( including SP2 ).
Step #2 Installed KB971831
Step #3 Ran the pre-req tool ( ran successful )
Step #4 Installed SPS 2010 > Chose Server Farm and chose StandAlone ( this would install SQL express 2008 )
Step #5 Installed Office Professional 2010
Step #6 Installed SharePoint Designer 2010
Step #7 Installed Visual Studio 2010 Beta
Step #8 Installed SQL Server Management Studio 2008
Step #9 Ran the Windows Update once again
Step #10 Take a snapshot

Voila!!!!

Thursday, December 17, 2009

Reading App.Config Key Values from Feature Folder

Title: Reading App.Config Key Values from Feature Folders
Details: We had a scenario where we need to have App.config under the Feature Folder. Keeping aside the need, the requirement was to read these values from a class thats inheriting SPItemEventReceiver which means I cannot use the Feature.xml properties. One way to accomplish this is as shown below. This is just a raw code, and you can tweak the code for best practices etc.
Code:

private string GetAppSettingValue(string key)
{
string ret = string.Empty;
string appconfigFilePath = Path.Combine(SPUtility.GetGenericSetupPath("TEMPLATE"), @"FEATURES\FEATURENAME\App.config");

ConfigXmlDocument document = new ConfigXmlDocument();
document.Load(appconfigFilePath);
XmlNodeList xmlNodeList = document.GetElementsByTagName("add");

for(int i=0; i < xmlNodeList.Count; i++)
{
if(xmlNodeList[i].Attributes["key"].Value.ToLowerInvariant() == key.ToLowerInvariant())
{
ret = xmlNodeList[i].Attributes["value"].Value;
}
}

return ret;
}

BreakRoleInheritance Method

Title: SPList.BreakRoleInheritance Method
Details: BreakRoleInheritance would break the inheritance ( can be used on a list / document library ) to alter permissions on the parent or itemlevel.
Usage:

public void BreakRoleInheritance (
bool CopyRoleAssignments
)

Accepts either true / false as parameter that would decide whether or not to copy the existing groups / users and permissions.

One interesting concept to note. Instead of using the below code that would remove all the groups and permissions from an item or list level after breaking the inheritance.


listItem.RoleAssignments.RemoveAll();


we can simple use as below


listItem.BreakRoleInheritance(false);

Removing Group / User Permissions on list item

Title: Removing Group / User Permissions on the List Item
Details: Some point of time you will encounter a scenario that you would want to remove permission of a group or user for a specific list item. So, here is what can be done.

Step # 1: Create a Feature and on Activation, Add Event Receivers to the List / Document Library

web.Lists[docLibraryName].EventReceivers.Add(SPEventReceiverType.ItemAdded, AssemblyName, ClassName);


Step # 2: On the Item Event Receiver, you can check for some validations ( or rules )etc and break the inheritance and remove the group.

private static void RemoveGroupPermissionsToTheItem(string groupName, SPWeb web, SPListItem listItem)
{
if (!listItem.HasUniqueRoleAssignments)
{
listItem.BreakRoleInheritance(true);

SPGroup group = web.SiteGroups[groupName];
listItem.RoleAssignments.RemoveById(group.ID);
}
}


Step # 3: On Feature Deactivation, make sure you delete the event handler on the list / documentlibrary


private void DeleteItemAddedEventReceiver(SPDocumentLibrary documentLibrary)
{
SPEventReceiverDefinitionCollection eventReceiverDefinitionCollection = documentLibrary.EventReceivers;

foreach (SPEventReceiverDefinition eventReceiverDefinition in eventReceiverDefinitionCollection)
{
if (eventReceiverDefinition.Assembly == AssemblyName && eventReceiverDefinition.Type == SPEventReceiverType.ItemAdded)
{
eventReceiverDefinition.Delete();
break;
}
}
}