Skip to main content

Karine Bosch

Go Search
Karine Bosch
  

The Silverlightness of SharePoint

  U2U Home
  U2U Course Calendar

 Other Belgian Bloggers

  Kris Vandermotten
  Peter Himschoot
  Serge Luca
  Bart De Smet
  Joris Poelmans
  David Boschmans
  Tom Mertens
  Stefaan Rillaert
  Yves Hanoulle
  Roy Dictus
The Silverlightness of SharePoint
Determine if MOSS is installed by checking the Registry key

Today I found a post that explains a way to determine if MOSS is installed by checking on the existence of certain folders. Another way is to check on the existence of its the registry key.

image

The RegistryKey class is located in the Microsoft.Win32 namespace of the mscorlib.dll.

string keyname = @"SOFTWARE\Microsoft\Office Server\12.0";

RegistryKey key = Registry.LocalMachine.OpenSubKey(keyname);
if (key != null)
{
    string version = key.GetValue("BuildVersion") as string;
    if (version != null)
    {
        Version buildVersion = new Version(version);
        if (buildVersion.Major == 12)
        {
            return true;
        }
     }
}

In a similar way you can determine if WSS is installed. In the registry you can find the following information:

image

Translated into code:

string keyname = @"SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0";

try
{
  RegistryKey key = Registry.LocalMachine.OpenSubKey(keyname);
  if (key != null)
  {
    object wssvalue = key.GetValue("SharePoint");
    if (wssvalue != null && wssvalue.Equals("Installed"))
    {
      return true;
    }
  }
  return false;
}

U2U Caml Query Builder (Windows version): new version

This version includes the following updates:

- Query fields by ID

- GetListItemChanges (method of the Lists.asmx web service)

- GetListItemChangesSinceToken (method of the Lists.asmx web service)

- extra options of the QueryOptions part

- support for data type ModStat 

You can download the version 3.1.0.0 here.

Remark for those who have put the dlls in the GAC: the version of U2U.SharePoint.CAML.dll has NOT been augmented so the users of the feature version are not bothered. The versions of U2U.SharePoint.CAML.Client.dll and U2U.SharePoint.CAML.Server.dll have also been raised to version 3.1.0.0 because of the changes. So users who use these dlls for custom development will have to check. But as I didn't remove any method, no interfaces should be broken.

Query fields by ID

In most of the cases list items are retrieved using the <FieldRef Name="x" /> syntax. But there are cases that you need to query by ID. In that case you can set the Query by ID option in the upper right corner of the form.

camlv2querybyid

Your query will look like the following:

camlv2querybyid2

Keep in mind that when you already built a query the default way and then choose to build the query by ID, your query will be cleared and you will have to start over again.

The ModStat data type

In case a column in your list is of data type ModStat, a combo box with the values Approved, Pending and Rejected will be displayed. A query containing such a field will look as follows:

<Where>
      <Eq>
         <FieldRef Name="_ModerationStatus" />
         <Value Type="ModStat">Approved</Value>
      </Eq>
</Where>

GetListItemChanges

With this method you can retrieve items that have been modified since a certain date. If you pass no date, all list items will be returned.

For a more in-depth explanation of this method I refer to:

- http://msdn2.microsoft.com/en-us/library/lists.lists.getlistitemchanges.aspx

To build a CAML query for the GetListItemChanges, open your site using the web service mode:

camlv2connectws

Right-click the list for which you want to build a query from the treeview at the left and choose GetListItemChanges:

camlv2getlistitemchanges1

You get 3 tabs to build your query:

- the ViewFields tab as in the GetListItems method

- the Contains tab where you can define a sort of filter

- the Since tab to specify a date

image

If you want to specify a date from which changed rows must be returned, check the Retrieve changes as of check box and choose a date from the date picker. In case you also need to specify a time, use the up/down controls. The date will be passed to the GetListItemChanges method.

GetListItemChangesSinceToken

With this method you can retrieve  list items that have been changed. On the first run of the method, the server returns all rows and a token. In the next runs you pass this token back to the server and only the modified rows since that token will be returned.

For a more in-depth explanation of this method I refer to:

- http://blogs.msdn.com/sharepointdeveloperdocs/archive/2008/01/21/synchronizing-with-windows-sharepoint-services-part-1.aspx

- http://msdn2.microsoft.com/en-us/library/lists.lists.getlistitemchangessincetoken.aspx

To build a CAML query for the GetListItemChangesSinceToken, open your site using the web service mode. Right-click the list for which you want to build a query from the treeview at the left and choose GetListItemChangesSinceToken.

You get 5 tabs to build your query:

- the ViewFields tab as in the GetListItems method

- the Query tab as in the GetListItems method where you can define a more complex filter and a sort order

- the Contains tab where you can define a sort of filter

- the ChangeToken tab to specify a token returned by the server

The Query tab and the Contains tab are mutually exclusive. This means that you can build a (more complex) filter with a WHERE clause or a simple CONTAINS filter.

image

The set of query options is a bit more extended for this method.

image

Don't forget, if you want to use the methods GetListItemChanges and GetListItemChangesSinceToken you can use the CAML generated by this tool but you can also use the underlying dlls U2U.SharePoint.CAML.dll and the U2U.SharePoint.CAML.Client.dll. If this is your case, don't hesitate to ask for a code sample!

How to modify the custom People/Groups type column of a SharePoint List using Lists.asmx

Based on this post I wanted to integrate Sowmyan's findings into the U2U CAML Query Builder. But I came to the conclusion that I can also update a user column in a list using the UpdateListItems method of the Lists.asmx web service with following query:

<Batch PreCalc='TRUE' OnError='Continue'>
   <Method ID='1' Cmd='Update'>
      <Field Name='ID'>12</Field>
      <Field Name='AssignedTo'>9</Field>
   </Method>
</Batch>

I don't specify a field type and for the user column I only specify the ID of the user I want to assign the task to.

To retrieve rows using the GetListItems method I couldn't use the ID of the user but I can use his/her name:

   <Where>
      <Eq>
         <FieldRef Name='AssignedTo' />
         <Value Type='User'>Karine Bosch</Value>
      </Eq>
   </Where>

Luckily it doesn't always need to be complicated image

Retrieving Items from a SharePoint List with Powershell and the SharePoint Lists.asmx

There is not yet much information on the net on how to combine Powershell with the SharePoint web services. One of the most used methods of the Lists.asmx, which is a standard SharePoint web service, is the GetListItems method. With this method you can retrieve all list items but also a subset of data when you use a CAML query. You can also limit the number of columns returned if you use a ViewFields node.

If you read previous posts and saved the necessary environment variable declarations in your profile, the only thing you should do to start is:

$listservice = New-Object Lists

$listservice.Credentials=[System.Net.CredentialCache]::DefaultCredentials

Otherwise you have to go back to my post and execute the first steps to declare the environment variables and compile and load the lists dll.

In its most simple form, you can retrieve all list items of a certain list:

$result = $listservice.GetListItems("Customers", $null, $null, $null, $null, $null, $null)

$result is an xml node containing the following:

image

It's the data element that contains the list items.

If you execute something like the following, you will get the last name of each customer in the result set:

$result.data.row | foreach ($_.ows_Title)

image

When working with the Lists.asmx SharePoint web service, all fields are prefixed with ows_.

If you want to retrieve a subset of list items you have to pass a CAML query to the GetListItems method. For example, if you want to retrieve all customers living in the city Bendigo, you have to create following CAML query:

<Query><Where><Eq><FieldRef Name='WorkCity' />

<Value Type='Text'>Bendigo</Value></Eq></Where></Query>

You execute the GetListItems method as follows:

$query = "<Query><Where><Eq><FieldRef Name='WorkCity' /><Value Type='Text'>Bendigo</Value></Eq></Where></Query>"

$result = $listservice.getlistitems("Customers", $null, $query, $null, $null, $null, $null)

image

You can always build your more complex queries with the U2U Caml Query Builder which exists in windows version (download) and feature version (download). Consult my blog or the U2U web site for more detailed information about building CAML queries with the tools. 

Another way to limit the number of rows returned is specifying a row limit, with or without a query:

$result = $listservice.getlistitems("Customers", $null, $query, $null, 3, $null, $null)

If you want to view the complete content of each row, you can execute the following:

image

You can also limit the number of columns returned in the result set by specifying a ViewFields node. Lets only retrieve the Title and Email for customers living in Bendigo:

[xml]$viewfields = "<ViewFields><FieldRef  Name='Title' /><FieldRef Name='EMail' /></ViewFields>

$result = $listservice.getlistitems("Customers", $null, $query, $viewfields, $null, $null, $null)

As you view the result you will notice that indeed the Title and the Email field are returned but also another bunch of fields. These are the system fields and will always be returned, even if you use the IncludeMandatoryColumns element of the QueryOptions (because this only works for custom fields defined as required). For completeness, you define QueryOptions as follows:

[xml]$queryoptions = "<QueryOptions><IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns></QueryOptions>"

$result = $listservice.getlistitems("Customers", $null, $query, $viewfields, $null, $queryoptions, $null)

You can read more about the GetListItems method on the msdn site.

If you need extra information about this method or about other method on other SharePoint web services, you can leave me a comment.

Nick, now you owe me a beer!

U2U Caml Query Builder Feature: new version

A new version of the U2U CAML Query Builder is released today!

This version includes the following updates:

- extra data types like ModStat: when selecting a column of type ModStat, a dropdown with possible values will be displayed

- it is now possibility to add more than 2 fields in the WHERE clause

- you can now build a query where the fields are filtered and sorted by ID instead of by name. This is because some type of queries require filtering by ID.

You can download the full U2U SharePoint Solution package here.

It contains features like List Properties, Site Properties and Move/Copy list items. (Only activate the feature you need).

How to add more filters to the where clause?

In the Filter On section fill out a first filter. If you want to add a second one, click the Add a column to the where clause hyperlink:

image

This adds a second filter to the Filter On section. You can add as many filters you need and indicate whether you want to Or or to And.

image

Click on the Preview button to see the actual query and the resulting data after running the query against the list:

 image

You can save your query and it will be saved to a specific CAML Query List from where you can use and preview your queries.

How to build a query to filter and sort fields by ID?

In the previous example the query was filtered by field name:

<FieldRef Name='LastName' />

But you can also execute a query with a filter and a sort by ID. To achieve this, there is a new section added under the query Name section:

image

The default is query by name but you can choose the option Query by field ID. The user interface stays the same but the previous query looks like this while the resulting data is still the same (don't forget to press the Preview button again):

<Query>
   <ViewFields>
      <FieldRef Name='EmployeeID' />
      <FieldRef Name='LastName' />
      <FieldRef Name='JobTitle' />
      <FieldRef Name='Phone' />
      <FieldRef Name='EmailAddress' />
   </ViewFields>
   <Where>
      <Or>
         <Or>
            <BeginsWith>
               <FieldRef ID='66cb931d-ff9c-47b2-8e13-d3554c1798af' />
               <Value Type='Text'>E</Value>
            </BeginsWith>
            <BeginsWith>
               <FieldRef ID='66cb931d-ff9c-47b2-8e13-d3554c1798af' />
               <Value Type='Text'>F</Value>
            </BeginsWith>
         </Or>
         <BeginsWith>
            <FieldRef ID='66cb931d-ff9c-47b2-8e13-d3554c1798af' />
            <Value Type='Text'>G</Value>
         </BeginsWith>
      </Or>
   </Where>
   <OrderBy>
      <FieldRef ID='13d408ed-79a3-4b67-a384-e4bac030df9d' Ascending='False' />
   </OrderBy>
</Query>

As you can see in this query all FieldRef elements in the Order By and the Where clause have an ID attribute, except the FieldRef elements in the ViewFields part. The weird thing is that when I replace the Name attribute with an ID attribute, only the ID field (and some other required fields) is returned. It seems ViewFields cannot handle the <FieldRef ID='[guid]' /> construct.

If you use this query against an SPQuery object, you have to:

- remove the <Query></Query> tags (I know this already caused a lot of confusion among the developers community but I need a root in an XML document)

- Assign the ViewFields node to the ViewFields property of the SPQuery object.

- Assign the Where and Order By node to the Query property of the SPQuery object.

This functionality and some other will be soon released in the windows version of the U2U CAML Query Builder.

Hope you like the new functionality!

Iterating through the columns of a list with Powershell and the SharePoint Lists.asmx web service

Yesterday I got a question on how to iterate through the columns of a list by using Powershell and the SharePoint Lists.asmx web service.

If you read previous post and saved the necessary environment variable declarations in your profile, the only thing you should do to start is:

$listservice = New-Object Lists

$listservice.Credentials=[System.Net.CredentialCache]::DefaultCredentials

Otherwise you have to go back to my last post and execute the first steps to declare the environment variables and compile and load the lists dll.

You can get access to the list by executing the GetList method on the Lists.amx web service. The required argument is the name of the list:

$list = $listservice.GetList("Employees")

You can view the title of the list:

$list.Title

Or the Guid:

$list.ID

image

You can get access to the fields (or columns) defined on your list by storing the field collection into a variable:

$fieldsnode = $listservice.GetList("Employees").Fields

But the return value of this Fields collection is an xml node. You can view the content of the field collection by executing the $fieldsnode.get_OuterXml() method but this returns you more than a page full of xml. But Powershell is smart enough to be able to handle the child nodes as objects. You can  view the different fields by executing f.e. the $fieldsnode.get_ChildNodes().

And now we come to iterating through the field collection. A field exposes properties like Name (which is the InternalName when working with the SharePoint object model), the ID, the DisplayName, Type and a lot of other properties. You can iterate through the field collection and retrieve the internal name as follows:

$fieldsnode.get_ChildNodes() | foreach-object { $_.Name }

image

 

Nick this one is for you! Thanks for reading my blog.

Update a SharePoint List remotely with PowerShell

Yesterday I got a comment on my blog post Update a SharePoint List with PowerShell asking if it is possible to remotely update a SharePoint list. This means that you have to execute the UpdateListItem method of the Lists.asmx web service of SharePoint.

It is possible to work with the SharePoint web services from within SharePoint. There are already some good posts around:

- Calling a Web Service from PowerShell which explains the steps to take before you can consume a Web Service

- Consuming SharePoint Web Services from PowerShell which explains how to get a list from the Lists Web Service.

In this post I'll explain the steps how to execute the UpdateListItem method.

First load the Visual Studio tools into your Powershell environment:

$env:VSINSTALLDIR="C:\Program Files\Microsoft Visual Studio 8"

$env:VCINSTALLDIR="C:\Program Files\Microsoft Visual Studio 8\VC"

$env:DevEnvDir="$env:VSINSTALLDIR\Common7\IDE"

$env:FrameworkSDKDir="$env:VSINSTALLDIR\SDK\v2.0"

$FrameworkPath=$([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())

$env:FrameworkDir=$(split-path $FrameworkPath -Parent)

$env:FrameworkVersion=$(split-path $FrameworkPath -Leaf)

$env:PATH="$env:VSINSTALLDIR\Common7\IDE;$env:VCINSTALLDIR\BIN;$env:VSINSTALLDIR\Common7\Tools;$env:VSINSTALLDIR\Common7\Tools\bin;$env:VCINSTALLDIR\PlatformSDK\bin; $env:FrameworkSDKDir\bin;$env:FrameworkDir\$env:FrameworkVersion;$env:VCINSTALLDIR\VCPackages;$env:PATH"

$env:INCLUDE="$env:VCINSTALLDIR\ATLMFC\INCLUDE; $env:VCINSTALLDIR\INCLUDE;$env:VCINSTALLDIR\PlatformSDK\include;$env:FrameworkSDKDir\include;$env:INCLUDE"

$env:LIB="$env:VCINSTALLDIR\ATLMFC\LIB; $env:VCINSTALLDIR\LIB;$env:VCINSTALLDIR\PlatformSDK\lib;$env:FrameworkSDKDir\lib;$env:LIB"

$env:LIBPATH="$FrameworkPath; $env:VCINSTALLDIR\ATLMFC\LIB"

As explained in other posts, you can put this in your profile so that these tools are loaded each time you run Powershell.

Then execute the following commands to compile the Lists web service:

PS>wsdl http://[site url]/_vti_bin/Lists.asmx

PS>csc /t:library Lists.cs

PS>[Reflection.Assembly]::LoadFrom("Lists.dll")

Once this is done you can place the following statement in your profile so that it is executed each time you run Powershell:

[void][Reflection.Assembly]::LoadFrom("Lists.dll")

Instantiate the lists web service:

PS> $listservice = New-Object Lists

You have to be authenticated to contact the web service:

$listservice.Credentials=[System.Net.CredentialCache]::DefaultCredentials

My example uses a computers list:

powershell updatelistitems before

There is a mistake in the title of the second item, which need to be corrected.

The method you need to use to update a list item is the UpdateListItems. This method asks for 2 arguments: the name of the list and a batch query. First a string is build with the CAML needed to update the list item and then the UpdateListItems method is executed:

PS>$query = "<Batch OnError='Continue'><Method ID='1' Cmd='Update'><Field Name='ID'>2</Field><Field Name='Title'>Laptop 2</Field></Method></Batch>"

PS>$listservice.UpdateListItems("Computers", $query)

In fact the second argument of the UpdateListItems method is an xml node but if the query string contains valid xml, it is implicitly converted into an xml node before it is passed to the UpdateListItems method. If you want to explicitly use an xml node you can write the following:

PS>[xml]$query = "<Batch OnError='Continue'><Method ID='1' Cmd='Update'><Field Name='ID'>2</Field><Field Name='Title'>Laptop 2</Field></Method></Batch>"

And here is the result of the udpate:

powershell updatelistitems after

For more information about working with xml nodes, i refer to the post of Dan Sullivan.

As you can see I can use CAML in a lot of different ways :)

Book of the month: Inside Index and Search Engine

My "boss" Patrick Tisseghems second book is available now. He wrote this juwel with his friend Lars Fastrup. If you are interested in Index and Search for MOSS 2007, this is a must-have!

InsideSearch

His book counts 640 pages and is a architectural guidance for deploying SharePoint Server 2007 and optimizing search.

Optimize the user search experience in your workplace by customizing and extending the enterprise search capabilities in SharePoint Server 2007. Recognized SharePoint experts deliver the straightforward guidance and pragmatic coding samples you need to enable quick access to critical information.
Discover how to:
• Configure and manage the SharePoint Server 2007 index file and search engines
• Plan a search deployment strategy that balances performance, scalability, and security considerations
• Set up and customize search functionality and UI controls
• Monitor and analyze search-usage metrics to optimize the end-user experience
• Use search APIs to prepare and execute a query, and to process the results
• Program administrative functions using the search administration object model
• Develop and install custom IFilters and protocol handlers
• Use the Business Data Catalog to structure and index critical line-of-business data
• Program search operations using Windows SharePoint Services 3.0

Enjoy reading!
The InitParameters Property of the SilverlightControl

When using Silverlight from within SharePoint you have to place a SilverlightControl on your web part, custom field type or application page. By setting the Source property you indicate which Silverlight application to run.

You can use the InitParameters property to pass values from SharePoint to Silverlight. But there is something weird about this property: at the Server side this property is a string and at the Silverlight side this property is a dictionary of KeyValuePairs where the value is always a string.

To construct the string so that it can easily be converted to a dictionary of KeyValuePairs by Silverlight you have to separate the different parameters by a comma and you have to place an equal sign between key and value:

silverlightControl.InitParameters = "key1=value1,key2=value2,key3=value3";

Don't place a blank between the comma and the next key because it will be added as the first character in the next key name.

In the App.xaml code behind you can then retrieve the keys and values from the EventArgs argument:

string value1 = null;

string value2 = null;

if (e.IniParams != null && e.InitParams.Count > 0)

{

value1 = e.IniParams["key1"];

value2 = e.IniParams["key2"];

}

If you need these values in your code behind of your xaml pages, pass them within the constructor of the page:

this.RootVisual = new Page(value1, value2);

Be aware that you cannot pass large chunks of data in the InitParameters property.

SharePoint Lists.asmx UpdateListItems: RootFolder

This week I read Jeffrey's post on how you can update a list item located in a sub folder using the RootFolder attribute on the UpdateListItems method of the Lists.asmx web service.

It seemed interesting enough to me to get this working in the U2U CAML Query Builder (windows version and feature version) so I started to implement it but I discovered that the truth about RootFolder is not as simple as it seems from this post.

Jeffrey states that the following code should work:

<Batch OnError="Continue" PreCalc="TRUE" ListVersion="0" RootFolder="Lists/Contacts/Work">
<Method ID="1" Cmd="Update">
<Field Name="ID">47821</Field>
<Field Name="RefID">479485</Field>
<Field Name="CustomerNumber">59613</Field>
</Batch>

I think that this code works because a valid ID is specified (in which case you even don't have to specify a RootFolder attribute: the item located in a sub folder can be updated specifying a valid ID). When I try this out without an ID I get an "Invalid URL" error.

The first thing I found out is that you have to make a difference between a list and a document library. In case of a list the root folder is indeed Lists, but you have to prefix it with a "/":

<Batch PreCalc="TRUE" OnError="Continue" RootFolder="/Lists/Cities/Europe/Belgium">
   <Method ID="1" Cmd="New">
      <Field Name="Title">Gent</Field>
      <Field Name="PostalCode">9000</Field>
      <Field Name="TelephoneZone">09</Field>
   </Method>
</Batch>

In case of a document library the root folder is the name of the document library, but it also needs to be prefixed with a "/":

<Batch PreCalc="TRUE" OnError="Continue"
    RootFolder="/Folders Doclib/2008/January">
   <Method ID="1" Cmd="New">
      <Field Name="Title">Document 2</Field>
      <Field Name="Income">2500</Field>
   </Method>
</Batch>

In case someone disagrees with this or if you have reasons to believe that even this is not complete, please let me know by posting a comment.

A new version of the U2U CAML Query Builder (windows version) will be ready to release end of this week. A new version of the feature version will be released a few weeks later. I keep you posted :)

1 - 10 Next
Silverlight BluePrint for SharePoint

 Recommended Books

Thumbnail
Thumbnail
Thumbnail
Thumbnail
Thumbnail
(More Items...)

 ‭(Hidden)‬ Admin Links