Saturday, April 30, 2011

Using SPSiteDataQuery to find list items by unique ID

In one of my projects I had to search for list item from current site collection by its unique ID that is kept in database as GUID. In this posting I will show you how to query list items by unique ID over current site collection.

Here’s the example query that works fine for me. Take a look at query – unique ID value must be set to type Lookup.


var queryString = @"<Where>

                        <Eq>

                            <FieldRef Name='Unique' />

                            <Value Type='Lookup'>{0}</Value>

                        </Eq>

                    </Where>";           

queryString = string.Format(queryString, taskIdString);

 

var query = new SPSiteDataQuery();

query.Query = queryString;

query.Webs = "<Webs Scope='SiteCollection' />";

query.Lists = "<Lists BaseType='0' />";

query.RowLimit = 1;

query.ViewFields = "<FieldRef Name='Title' />
                    <FieldRef Name='ID' />
                    <FieldRef Name='UniqueId' />"
;


Besides fields defined in ViewFields property the results contain also web and list ID-s where item belongs.

This is the helper method I use to find workflow task with given unique ID. I’m using this code on page where workflow is not present.


public SPListItem GetListItemByUniqueId(Guid uniqueId)

{

    var queryString = @"<Where>
                       <Eq>
                       <FieldRef Name='UniqueId' />
                       <Value Type='Lookup'>{0}</Value>
                       </Eq>
                       </Where>"
;

    queryString = string.Format(queryString, uniqueId);

 

    var query = new SPSiteDataQuery();

    query.Query = queryString;

    query.Webs = "<Webs Scope='SiteCollection' />";

    query.Lists = "<Lists BaseType='0' />";

    query.RowLimit = 1;

    query.ViewFields = @"<FieldRef Name='Title' />
                         <FieldRef Name='ID' />
                         <FieldRef Name='UniqueId' />"
;

 

    var results = SPContext.Current.Web.GetSiteData(query);

    if (results == null)

    {

        return null;

    }

    if (results.Rows.Count == 0)

    {

        return null;

    }

 

    var listId = new Guid(results.Rows[0]["ListId"].ToString());

    var list = SPContext.Current.Web.Lists[listId];

    return list.GetItemByUniqueId(uniqueId);

}


As you can see there’s code enough to keep it in separate method. You can use this method in your own code and you can also modify and improve it to better fit your needs.

Wednesday, April 13, 2011

Free webinar: Architecting a Disaster Tolerant SharePoint 2010 Farm (04/14/2011)

SharePoint Pro organizes free webinar on 04/14/2011 where speakers Michael Noel and David Beeler discuss about disaster tolerant SharePoint 2010 farms. Event starts 12:00 p.m. ET / 09:00 a.m. PT / 17:00 GMT.

Description

This session covers best practice design and planning for setting up a highly redundant SharePoint Server 2010 environment. Technologies such as Network Load Balancing of SharePoint web role servers, creating redundant service application servers are covered in depth, and tips and tricks for the deployment of redundancy in a SharePoint environment are presented. In addition, specifics on how to leverage SQL Server Database Mirroring technologies for remote data replication of SharePoint content databases is covered in detail.

Speakers

  • Michael Noel - MVP for SharePoint Server and an MCSE+I. He has been involved in the computer industry for nearly two decades, and has significant real-world experience helping organizations realize business value from Information Technology. Michael has authored several major best-selling industry books that have been translated into seven languages with a total worldwide circulation of over 150,000 copies.
  • David Beeler - product development manager for the applications and clusters team at Vision Solutions, Inc. He specializes in providing high availability/disaster recovery software and solutions for enterprise SQL, SharePoint, and Exchange environments.

You can register yourself on webinar homepage.

10 interactive SharePoint 2010 labs by Microsoft

Microsoft has published some simple and nice interactive labs under title Build a better app that help you to get started with SharePoint 2010 development on Visual Studio 2010. Each lab should take about 15 minutes of your valuable time. Here’s the list of labs:

  1. Designing Lists and Schemas
  2. Developer Roadmap
  3. Developing Sandboxed Solutions
  4. Enterprise Content Management
  5. LINQ to SharePoint
  6. User Interface (UI) Enhancements
  7. Visual Studio SharePoint Tools
  8. SharePoint 2010 Best Practices
  9. Upgrading a VSeWSS Project to Visual Studio
  10. Installing and Upgrading Custom Solutions

If you take all this labs then 2-3 hours of your life should be very interesting.

Friday, April 8, 2011

Failed to get value of the "Approval Status" column from the "Moderation Status" field type control

When upgrading site from SharePoint 2007 to SharePoint 2010 or if somebody has tried to be extreme smart-ass you may get the following error when saving item or document to list where content approval is turned on: Failed to get value of the "Approval Status" column from the "Moderation Status" field type control.  See details in log. Exception message: Input string was not in a correct format.

Solution 1

I found one solution from TechNet forum thread can't edit doc. properties - error Failed to get value of the "Approval Status" column from the "Moderation Status" field ty. Steps to solve the problem are here:

  1. Download SharePoint Manager 2010 and run it as an administrator. You have to wait a little bit until it starts up so be patient.
  2. Navigate to problematic list and select moderation status field.
  3. Set Hidden property value to True.
  4. Save changes (there are save icons on left side on toolbar).
  5. Try saving again.

This problem may occur after you migrated your site from SharePoint 2007 to SharePoint 2010.

Solution 2

The second case where I have seen this problem is when list schema in deployment package contains definition for moderation status field with preset values. The fields section of schema.xml contains something like this:


<Field ID="{fdc3b2ed-5bf2-4835-a4bc-b7d1a6396a61}"         ReadOnly="FALSE"         Type="ModStat"         Name="_ModerationStatus"         StaticName="_ModerationStatus"        DisplayName="Approval Status"         Hidden="FALSE"         CanToggleHidden="TRUE"         FromBaseType="TRUE"       Required="TRUE"  SourceID="http://schemas.microsoft.com/sharepoint/v3">   <CHOICES>     <CHOICE>0;#Approved</CHOICE>     <CHOICE>1;#Rejected</CHOICE>     <CHOICE>2;#Pending</CHOICE>     <CHOICE>3;#Draft</CHOICE>     <CHOICE>4;#Scheduled</CHOICE>   </CHOICES>   <Default>2</Default> </Field>

To solve the problem just remove this field definition from schema.xml and deploy your list template to server again. Of course, you have to create also list instances again that are based on this template.

Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive

When IIS is not configured properly after creating SharePoint application and there are web parts or features that use session you may get the following error: Unexpected error occured: System.Web.HttpException: Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive. Please also make sure that System.Web.SessionStateModule or a custom session state module is included in the \\ section in the application configuration.

Solution

As a solution you must register session state handler module in IIS.

  1. Open Internet Information Services manager.
  2. Move to site where problem occurred.
  3. Open modules list of this site.
  4. Add session state handler like show on the following image (click on it):
     
     IIS: Set session state module
     
  5. Click OK, recycle application pool and refresh the page.

I am not very sure why SharePoint doesn’t enable this module by default as mostly default session state module is enough.

Unable to locate the xml-definition for CType with SPContentTypeId

When deploying your SharePoint solution to your development or test server where solution has been deployed before you may find errors like these in SharePoint log: Unable to locate the xml-definition for CType with SPContentTypeId <Content type ID here> and Failed to find the content type schema for ct-0-0x010100<Content type ID> during template lookup.

Symptoms

The exact reason for these errors is still unknown to me but symptom is clear: I have seen these errors happen in environments where deployed package was deployed before. I have seen this problem happen on development and test environments mainly. For production deployments you should anyway start with clean installation of servers and handle all deployments with special care.

As this error is not directly shown you when you deploy your solution you may detect it later through weird behavior of layout pages. When adding new publishing page to pages library you may get unexpected errors. From logs you can find errors stated above.

Solution

NB! Before applying the fix to your solution make sure you make backups of SharePoint and test these changes completely so you are 100% sure that these changes doesn’t have negative side effects on data you already have.

To get over these errors I added Overwrite=”TRUE” to problematic content type definition.


<ContentType  ID="0x010100C568DB52D9D0A14D9B2FDCC142166E9F2" Name="$Resources:my,MyCT_Name" Description="$Resources:my,MyCT_Description" Group="My" Overwrite="TRUE" Inherits="TRUE" Version="0">   <FieldRefs>     <FieldRef ID="{C7B4C971-3AE9-46FF-9354-13E31ADD9C30}" Name="Age"/>     <FieldRef ID="{E2DDA75E-C9E0-4D8F-A489-71C764293E47}" Name="Income"/>   </FieldRefs> </ContentType>

After these changes deployment succeeded with no problems on content types.

Saturday, April 2, 2011

Users are registered but not authenticated when using FBA and claims-based authentication

Configured one SharePoint 2010 web application to use FBA with claims-based authentication. I also created extended application that is internally used as for administrative purposes. On public site users were registered but never correctly authenticated for SharePoint. Solution is here.

Make sure at least one of applications has Windows authentication enabled. For one server I had to make NTLM available also for internet zone although it is not used there and users are redirected to custom login page when they are entering the site.

cba-ntlm

After enabling NTLM users were able to authenticate using Forms Based Authentication.

Cannot use SharePoint 2010 API from console application

Suppose you create new console application using Visual Studio 2010 and add reference to SharePoint 2010 main library. When you run application you get the following error: Retrieving the COM class factory for component with CLSID {BDEADF26-C265-11D0-BCED-00A0C90AB50F} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)). Same error may also occur in ASP.NET applications that use SharePoint 2010. Here’s the solution.

Make sure you are using .NET Framework 3.5 as target framework. Your application is compiled to 64bit platform.

sp2010-target-platform-64bit

Now compile your app and try to run it. Everything should work fine now.