Thursday, December 22, 2011

Unable to get List data present in Claims Based Web Application

Hi All,

Recently we faced the problem of not able to pull data that is present in Windows Authenticated Web Application from a Claims Based Web Application. These two web apps are on same server.

Tried all possible ways like LINQ to SharePoint, Client Object Model, 2007 lists.asmx etc. but no luck

Finally, we have added a registry key called "DisableLoopBackCheck" and set its value to 1.

More information on this can be found here

Cheers !

Tuesday, December 20, 2011

Read Credentials from Secure Store Service Programatically in SharePoint 2010

Hello,

If you want to read the credentials set in secure store service programatically, then the below code is helpful.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Runtime.InteropServices;
using System.Security;
using Microsoft.BusinessData.Infrastructure.SecureStore;
using Microsoft.Office.SecureStoreService.Server;


namespace ReadSecureStoreCredentials
{
    public static class SecureStoreUtils
    {
        public static Dictionary<string, string> GetCredentials(string applicationID)
        {
            var credentialMap = new Dictionary<string, string>();
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                SPSite site = SPContext.Current.Site;
                SPServiceContext serviceContext = SPServiceContext.GetContext(site);
                var secureStoreProvider = new SecureStoreProvider { Context = serviceContext };
                using (var credentials = secureStoreProvider.GetCredentials(applicationID))
                {
                    var fields = secureStoreProvider.GetTargetApplicationFields(applicationID);
                    for (var i = 0; i < fields.Count; i++)
                    {
                        var field = fields[i];
                        var credential = credentials[i];
                        var decryptedCredential = ToClrString(credential.Credential);

                        credentialMap.Add(field.Name, decryptedCredential);
                    }
                }
            });
            return credentialMap;
        }

        public static string ToClrString(this SecureString secureString)
        {
            var ptr = Marshal.SecureStringToBSTR(secureString);

            try
            {
                return Marshal.PtrToStringBSTR(ptr);
            }
            finally
            {
                Marshal.FreeBSTR(ptr);
            }
        }
    }
}


Make sure you have added the following dll's

1. Microsoft.Office.SecureStoreService.dll located at C:\Windows\assembly\GAC_MSIL\Microsoft.Office.SecureStoreService\14.0.0.0__71e9bce111e9429c\Microsoft.Office.SecureStoreService.dll and

2. Microsoft.BusinessData.dll located at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.BusinessData.dll

And here is how you make use of the above code to read credentials from secure store service

Dictionary<string, string> SSCredentials = SecureStoreUtils.GetCredentials("SecureStoreId");
string strDU = SSCredentials.ElementAt(0).Value;
int SlashPos = strDU.IndexOf('\\');
this.strDomainName = strDU.Substring(0, SlashPos);
this.strUserName = strDU.Substring(SlashPos + 1, strDU.Length - this.strDomainName.Length - 1);
this.strPassword = SSCredentials.ElementAt(1).Value;


Bye for now :)

Saturday, December 10, 2011

Error occurred in deployment step 'Recycle IIS Application Pool': A timeout has occurred while invoking commands in SharePoint host process.

Hello,

We got the below error while trying to deploy SharePoint solution

Error occurred in deployment step 'Recycle IIS Application Pool': A timeout has occurred while invoking commands in SharePoint host process.

Thr possible reasons for this error as per MSDN forums are:

1. Less System Resources, possible <6 GB of RAM. (Recommended RAM for SP 2010 is >=6GB)

2. Application Pools might be stopped.

In my case, both these possibilities doesnot apply.

The solution to eliminate this error is:

Increase the Shutdown Time Limit and Startup Time Limit under Application Pool -> Advanced Settings.

This resolved the above error:)

Hidden SharePoint List - User Information

Hello Again,

There is a hidden list in SharePoint which stores the User Details like Name, Email, Login Name etc.

We can access this list using the URL:

http://WebApplicationName/_catalogs/users/simple.aspx

Here, when ever a new user is added to the sharepoint site, firstly that user will be added to this list. Hence, we can consider this list as a resource of all users present in the site.

We can acess this list through object model as:

SPList hiddenUserList = SPContext.Current.Web.SiteUserInfoList; 

Note that this list contains the users which are deleted from Active Directory too. Hence, whenever we delete a user from SharePoint site, its actually a soft delete and that user details still exist in this hidden list.

SharePoint Rocks !!!

Get User Details by ID in SharePoint 2010

Hello,

If you want to get the user details like Name, Email and other details of SharePoint user based on ID (Example: 12;domain\username), then the below code will be useful

SPContext.Current.Web.AllUsers.GetById(12).Email

Thursday, December 1, 2011

Windows Powershell Command Builder

Hello there,

Here is an useful tool from Microsoft called as "Windows Powershell Command Builder" which gives basic information about Powershell Commands. Thanks to my colleague for suggesting this tool :)

Windows Powershell Command Builder

There are two sections in this tool.

1. Verbs
2. Nouns

Verbs section contains all basic command names such as "Add", "Backup", "Install" etc.
Nouns section contains the target on which the verb acts. For example, Farm Solution, Sand box Solution, Site etc.

To use this tool, just drag one of the command in Verbs section and one of the command in Nouns section into Design Surface. Then, you will get a basic command. For example, Add-SPSolution etc.

Once you get the command, you can copy this command to Clipboard.

The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters.

Hello Again !

We usually get this common error when trying to deploy a package containing files of length greater than 260 characters. VS 2010 showed this error in feature.

The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters.

At first glance, the obvious solution which we feel is to reduce the file names in the solution. I tried the following approaches:

1. Reduced the file names in my solution especially the SharePoint Mapped Layouts Folder.
2. Changed the VS 2010 Project directory from C:\Users\saiabhilash\Documents\Visual Studio 2010\Projects to C:\MyProjects but got the same error !

OK! The resolution to this problem is to change the Deployment Path for the Feature. Double Click on the Feature and click F4 by selecting the feature. By Default, the Deployment Path for a features looks like this

"$SharePoint.Project.FileNameWithoutExtension$_$SharePoint.Feature.FileNameWithoutExtension$"

We have deleted the First Portion of this string and modified the path as

"CompanyName_$SharePoint.Feature.FileNameWithoutExtension$"













With this change, we were able to get rid of the above error :)

Failed to instantiate file "Home.aspx" from module "SitePagesModule": The specified list does not exist

We have a module in our SharePoint 2010 VS project which deploys the custom aspx pages in site pages document library.

Whenever we try to deploy this project, we get the below error:

Failed to instantiate file "Home.aspx" from module "SitePagesModule": The specified list does not exist

The possible solutions to this problem can be:

1. Delete the Module which deploys the site pages and add them again
2. In Elements.xml of the SitePages Module, change the Type Attribute value from "GhostableInLibrary" to "Ghostable" as shown below
<File Path="SitePagesModule\Home.aspx" Url="Home.aspx" Type="Ghostable" IgnoreIfAlreadyExists="TRUE" />

This is it. Now, the above error stopped flashing again :)

Happy SharePointing !

Thursday, November 24, 2011

The closed type does not have a corresponding "CustomerId" settable property

We got this issue when pulling data from a SharePoint list using REST Web services (used LINQ to SharePoint)

Earlier, the code worked fine and then we added a column in the SharePoint list (Column Name is "Customer"). Then, we started getting this error which contains the column name too. (CustomerId)

So, we updated the service reference (i.e http://sharepointsite/listname/_vti_bin/listdata.svc) and the error vanished.

Hope this helps :)

Tuesday, November 22, 2011

Programatically change Site and System Master Page in SharePoint 2010

Here is the code to change both Site and System Master Page in SharePoint 2010.

This code has been written in Event Receiver. When the feature is deactivated, automatically, v4.master is applied

 public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPSite oSite = (SPSite)properties.Feature.Parent;

            using (SPWeb oWeb = oSite.OpenWeb())
            {
                oWeb.MasterUrl = oWeb.ServerRelativeUrl + "/_catalogs/masterpage/CustomMaster.master";
                oWeb.CustomMasterUrl = oWeb.ServerRelativeUrl + "/_catalogs/masterpage/CustomMaster.master";
                oWeb.Update();
            }
        }


        // Uncomment the method below to handle the event raised before a feature is deactivated.

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPSite oSite = (SPSite)properties.Feature.Parent;

            using (SPWeb oWeb = oSite.OpenWeb())
            {
                oWeb.MasterUrl = oWeb.ServerRelativeUrl + "/_catalogs/masterpage/v4.master";
                oWeb.CustomMasterUrl = oWeb.ServerRelativeUrl + "/_catalogs/masterpage/v4.master";
                oWeb.Update();
            }
        }


Here, oWeb.MasterUrl refers to System Master Page and oWeb.CustomMasterUrl refers to Site Master Page.

Cheers !

Friday, November 11, 2011

The operation that you are attempting to perform cannot be completed successfully. No content databases in the web application were available to store your site collection.

We got this issue when trying to restore a site collection backup file in a web application.

The operation that you are attempting to perform cannot be completed successfully. No content databases in the web application were available to store your site collection. The existing content databases may have reached the maximum number of site collections, or be set to read-only, or be offline, or may already contain a copy of this site collection.

The reason for this error is that we have restored the backup file already in a different site collection in same web application. We got this error when trying to restore the same backup file in different site collection in same web application.

SharePoint 2010 by default accepts a backup file to be restored only once for a content database. Hence, whenever we are trying to restore the backup file to different site collection in same content database, we got this error.

The Resolution for this issue is to restore the backup file in different web application. This makes sure that the backup file is restored in a new content database. Cheers !

Monday, November 7, 2011

Unable to Add Custom Workflow Action in SharePoint Designer

Developed a Custom Workflow Activity for SharePoint 2010 Workflow using the link here.

Every thing went well and we were able to see the custom action in Actions tab in SharePoint 2010 Designer but when trying to add them, the action is not getting added.

This is the most common issue that everyone encounters. Here are the possible mistakes that leads to this problem.

1. Check if you have added the entry in web.config which looks like this
<authorizedType Assembly="Namespace.ClassName, Version=1.0.0.0, Culture=neutral, PublicKeyToken="Your Public Key Token" Namespace="Namespace" TypeName="*" Authorized="True" />
2. Check if there is not more than one character space between elements in .ACTIONS file

Remember that SPD caches the .ACTIONS file. Hence, after making appropriate changes, do an IIS Reset and Restart your SharePoint Designer.

If everything is correct, you will see that your custom action will be added to designer.

Happy SharePointing :)

The workflow could not update the item, possibly because one or more columns for the item require a different type of information

We got this strange issue when trying to update the current item through workflow.

Since the workflow error states that it requires different type of information, we thought it was the issue with data type mismatch but it was not the data type issue.

This issue is because the list workflow is configured to run in both cases:
a. When Item is Created
b. When Item is Modified

Hence, whenever the workflow tries to update the current item, a new workflow instance tries to start but since the current workflow instance is not yet completed, SharePoint flags this type of error.

Work Around: To resolve this issue, we have configured the list to start only when a new item is created.

We now used Event Receivers to trigger the workflow when the item is updated. In this case, the current workflow stops before a new workflow starts. Problem Solved :)

Sunday, November 6, 2011

Property Bags in SharePoint 2010

Property Bags enables the developers to add properties to the SharePoint objects like

a. Farm (SPFarm class)
b. Web application (SPWebApplication class)
c. Site collection (SPSite class)
d. Site (SPWeb class)
e. List (SPList class)

Using Property Bags, developers can avoid storing Key/Value pairs in Web.Config or at some other location. Internally, Property bags are implemented as a hash table of property names and values.

We can set the Property Bag values using two ways:
a. Using SharePoint Designer
b. Programatically

a. Using SharePoint Designer to store Property Bags
(i). Open the site in SP Designer 2010 and click on Site Options.







(ii). Under Parameters, click on Add and Start Adding Key/Value Pairs !


















To read this MyKey value, just use the below code.

SPSite siteCollection = new SPSite("http://sharepoint");
SPWeb website = mySite.RootWeb;
string MyValue = website.AllProperties["MyKey"]);


b. Programatically.

Use the below code to set the property bags Programatically.

SPSite siteCollection = new SPSite("http://sharepoint");
SPWeb website = mySite.RootWeb;
website.Properties.Add("MyKey", "MyValue");
website.Properties.Update

Content Type Hub in SharePoint 2010

What if we need to reuse a content type created in a web application "X" to be reused in web application "Y" in the same farm ?

In SharePoint 2007, we don't have any option to export the content type but recreate the content type in web application "Y".

Thanks to Content Type Hub in SharePoint 2010, we can reuse the content type across the web applications in the same farm.

Content Type Hub is a centralized location (Generally a separate site collection) in the farm and it stores all the content types which can be reused across multiple web applications.

Below is the step by step procedure to setup content type hub

1. Create a new site collection (Preferably a root site collection in some web application. Say http://sharepoint:37615)

2. Go to Central Admin - Manage Service Applications and click on Managed Metadata Service and click on Properties













3. At the End of the "Create New Managed Metadata Service" popup, provide the url of the site collection which needs to act as Content Type Hub. Here, in this case its http://sharepoint:37615 and check the "Report syndication import errors" below if you want to track the errors. Click OK.



















4. Now, select "Managed Metadata Service" Connection and click on properties.

5. Check the 3rd option which is uncheck by default. With this, we are explicitly asking the SharePoint Web Applications to consume content types that are available in our content type hub










6. Now go to content type hub site http://sharepoint:37615 and create a new content type (Say TestContentType)














7. Under Settings for the new content type, click on "Manage publishing for this content type".



















8. Click "Publish"













9. Note that the published content type i.e. "TestContentType" will not appear immediately in other web applications. There are two timer jobs which does all the synchronization stuff between content type hub and other web applications.

10. Start these timer jobs manually. (Content Type Hub and Content Type Subscriber)







11. Thats it. The new content type is now globally available to all web applications in the farm which are using the same "Managed Metadata Service" Application

12. You can check that by going to Site Collection Administration - Content Type Publishing and our new content type is available in different site collection :)

SharePoint Designer cannot display the item

Recently i developed a workflow in SharePoint Designer 2010 which includes a custom activity in it.

It worked well and suddenly after making some changes to the custom activity code, i got an error "SharePoint Designer cannot display the item" and from then i am unable to open the workflow.











Obviously, its because of code error in Custom Activity. But I cannot directly remove the reference to custom activity since I am unable to open the workflow in designer.

The workaround for this problem which i found is that simply edit the Workflows XOML file and remove the custom activity reference from it. Thats it !







































Remember, SPD caches the workflow files. Hence, restart your SharePoint designer and you can open the Workflow in Designer :)

Add users to SP Group Programatically for a Claims Based Web Application

Here's the code to Add users to SharePoint Group Programatically for a Claims Based Web Application

Note that we need to add claims token to the user name before adding them to the group since its a claims based web application.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AddUsers.UserGroup;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration.Claims;

namespace AddUsers
{
    class Program
    {
        static void Main(string[] args)
        {
            using (UserGroup.UserGroup userService = new UserGroup.UserGroup())
            {
                String uriVal = "http://site/sites/testsite/_vti_bin/UserGroup.asmx";
                String userName = String.Empty;
                userService.Url = uriVal;
                userService.Credentials = new System.Net.NetworkCredential("username", "password", "domain");
                SPClaimProviderManager ClaimManager = SPClaimProviderManager.Local;
                if (ClaimManager != null)
                {
                    try
                    {
                        SPClaim claim = new SPClaim(SPClaimTypes.UserLogonName, "username", "http://www.w3.org/2001/XMLSchema#string", SPOriginalIssuers.Format(SPOriginalIssuerType.Windows));
                        userName = ClaimManager.EncodeClaim(claim);
                    }
                    catch (Exception ex)
                    {
                    }
                }
                userService.AddUserToGroup("Approvers", userName, userName, "useremail", "");

            }
        }
    }
}

Get Site Collection Usage in SharePoint 2010 Programatically.

Here's the code to get Site Collection Usage in SharePoint 2010 Programatically.

using (SPSite site = new SPSite("http://WebAppName/sites/SiteCollectionName"))
{
   Console.Write("Site Collection Usage (in MB’s) is: " + site.Usage.Storage/(1024*1024) + "MB");
}