Nick Grattan's Blog

About Microsoft SharePoint, .NET, Natural Language Processing and Machine Learning

Archive for the ‘SharePoint Object Model’ Category

Opening Web Parts Gallery Programmatically

leave a comment »

Navigating to the Web Part Gallery in the browser interface takes you to http://site collection URL/_layouts/_catalogs/wp/Forms/AllItems.aspx. Attempting to open the list through “_catalogs/wp” will fail:


SPList spWPG = spWeb.Lists["_catalogs/wp"];  // does not work

 Instead, you need to use the following code:


SPList spWPG = spWeb.Lists["Web Part Gallery"];

Reference: http://meiyinglim.blogspot.com/2007/10/programatically-organizing-web-parts-in.html

Written by Nick Grattan

June 23, 2011 at 12:21 pm

When a SPFieldUserValueCollection won’t clear

leave a comment »

Some time ago I wrote about problems with updating items through an item collection (see here). Well, here’s another similar problem that has bitten me, and it’s to do with updating a SPFieldUserValueCollection object.

In this code I want to clear out the list of users configured for a multi-select user column in a list:

                SPListItem li = ...; // get a list item
                SPFieldUserValueCollection uvc = (SPFieldUserValueCollection)li["View Form Groups"];
                if (uvc != null)
                {
                    uvc.Clear();
                }
                li.Update();

The code gets the SPFieldUserValueCollection object for the field, and if it’s not null, empties the collection and updates the item.

However, the list of users is not cleared in the list item. It seems that a copy of the collection is made, and it’s the copy that is cleared. Here’s the code to correct this problem:

                SPListItem li = ...;
                SPFieldUserValueCollection uvc = (SPFieldUserValueCollection)li["View Form Groups"];
                if (uvc != null)
                {
                    uvc.Clear();
                    li["View Form Groups"] = uvc;
                }
                li.Update();

In this case, the modified SPFieldUserValueCollection is copied back into the field and the list item updated.

Written by Nick Grattan

January 2, 2011 at 9:58 am

Code for Creating New Documents based on a content type and template

with 15 comments

This method “CreateDocument” will create a new document in a SharePoint document library using a content type. It will copy the document template associated with the content type into the new document:

// Creates document in given list (root folder).
// Returns true if the file was created, false if it already
// exists or throws exception for other failure
protected bool CreateDocument( string sFilename,
                string sContentType, string sList)
{
    try
    {
        SPSite site = SPContext.Current.Site;

        using (SPWeb web = site.OpenWeb())
        {
            SPList list = web.Lists[sList];
            // this always uses root folder
            SPFolder folder = web.Folders[sList];
            SPFileCollection fcol = folder.Files;

            // find the template url and open
            string sTemplate =
                list.ContentTypes[sContentType].DocumentTemplateUrl;
            SPFile spf = web.GetFile(sTemplate);
            byte[] binFile = spf.OpenBinary();
            // Url for file to be created
            string destFile = fcol.Folder.Url + “/” + sFilename;

            // create the document and get SPFile/SPItem for
            // new document
            SPFile addedFile = fcol.Add(destFile, binFile, false);
            SPItem newItem = addedFile.Item;
            newItem["ContentType"] = sContentType;
            newItem.Update();
            addedFile.Update();
            return true;
        }
    }
    catch (SPException spEx)
    {
        // file already exists?
        if (spEx.ErrorCode == -2130575257)
            return false;
        else
            throw spEx;
    }
}

This code:

  1. Gets a SPSite for the current site collection, and opens an SPWeb for the site.
  2. Gets a SPList for the given list, and then an SPFolder for the root folder in this list. This code always creates the document in the root folder, but the code can easily be changed to place the document in any folder in the document library.
  3. Gets a SPFileCollection for the documents in the folder.
  4. “DocumentTemplateUrl” is used to return the Url of document template associated with the given content type.
  5. Get an SPFile for the document template in spf and open it for binary access using OpenBinary
  6. Add a new document to the folder through the SPFileCollection referenced by fcol.
  7. Get an SPItem for the new document and set the “ContentType” column to ensure it uses the correct content type (it will default to the first content type in the document library).
  8. Update the item and the added file.
  9. The catch section checks for an -2130575257 error, which indicates the file already exists.

 

Written by Nick Grattan

December 8, 2008 at 10:23 pm

Trimming WebPart Output with SPSecurityTrimmedControl

with one comment

The SPSecurityTrimmedControl can be used in your SharePoint pages and web parts to conditionally display content based on permissions assigned to a user.

Here’s an example of using the control in a web part. The control is declared in Microsoft.SharePoint (in microsoft.sharepoint.dll). First, create an instance:

SPSecurityTrimmedControl stcEditItem= new SPSecurityTrimmedControl();
stcEditItem.Permissions = SPBasePermissions.EditListItems;

Next, specify the output to display only if the current user has the given permissions. In this case

  • Define a literal server control, add some content
  • Add the literal to the SPSecurityTrimmedControl
  • Add the SPSecurityTrimmedControl to the controls collection for the web part:

Literal litEditItem = new Literal();
litEditItem.Text = “My Content”;
stcEditItem.Controls.Add(litEditItem);
this.Controls.Add(stcEditItem);

Finally, you can explicitly render the SPSecurityTrimmedControl control in the web part’s “Render” method:

stcEditItem.RenderControl(writer);

The content “My Content” will only be displayed in the web part if the user has the “EditListItems” permission.

Also, you can programmatically test for permissions on various SharePoint objects, such as SPListItem, using the AllRolesForCurrentUser method:

SPListItem li;

if (!li.AllRolesForCurrentUser.Contains(web.RoleDefinitions["Approve"]))
{
    …

This web post from Richard Harbridge shows how to use the SPSecurityTrimmedControl in an ASPX page.

Written by Nick Grattan

November 13, 2008 at 1:05 pm

When an SPListItem won’t Update or Change

with 2 comments

Here’s a problem that recently bit me. This code executes a query that returns a single SPListItem and then attempts to change the approved status through the SPListItemCollection:

SPListItemCollection lic = list.GetItems(query);
lic[0].ModerationInformation.Status = SPModerationStatusType.Approved;
lic[0].Update();

Strangely enough, before calling the change to “Status” (second line) the status was “Pending” and *after* the call the status was still “Pending”!

However, assigning to a SPListItem and updating through this object changes the approved status as expected:

SPListItemCollection lic = list.GetItems(query);
SPListItem li = lic[0];
li.ModerationInformation.Status = SPModerationStatusType.Approved;
li.Update();

It seems the SharePoint object model cannot handle repeated calls through the item collection to the same list item object – perhaps it creates a new temporary object each time?

Written by Nick Grattan

November 12, 2008 at 8:27 pm

SharePoint 2007 Custom Fields and “Edit property on server”

with 5 comments

When developing custom fields in SharePoint 2007 you may encounter this warning when adding the field to a document library but not to a list:

“The field type cannot be edited from most client programs and might block the programs from saving documents to this library.”

Cf1

The warning is given because an ASPX control is used for editing the column/property values in SharePoint but this ASPX control cannot be used for editing column values in client applications such as Microsoft Word. When a document is created in Microsoft Word the column is shown with the “Edit property on server” error:

Cf2

To allow the column to be edited in client applications you need to specify a parent type for the field. This parent type is one of the standard field types that a client application can edit. You then specify that the parent type edit mechanism (such as a standard edit box or combo box) can be used by setting the AllowBaseTypeRendering property for the field.

To do this edit the fldtypes_*xml file for the custom field; add the AllowBaseTypeRendering Field element with the value “TRUE” and set the ParentType field element to a standard field type, such as “Number”:

<Field Name=TypeName>RatingField</Field>

<Field Name=ParentType>Number</Field>

<Field Name=SQLType>float</Field>

<Field Name=TypeDisplayName>Rating Field</Field>

<Field Name=TypeShortDescription>Rating Field</Field>

<Field Name=Sortable>TRUE</Field>

<Field Name=AllowBaseTypeRendering>TRUE</Field>

<Field Name=Filterable>TRUE</Field>

The field will now be editable in client applications like Microsoft Word.

Written by Nick Grattan

January 6, 2008 at 2:18 pm

Extract Public Key from Signed Assembly – Method 2

leave a comment »

In this post I show how to extract the public key token from a signed assembly using the “sn” utility.

If the signed assembly is already installed in the GAC you can use the Windows Explorer to find the public key token:

  • Run Windows Explorer.
  • Navigate to the \Windows\assembly folder.

List of assemblies displayes the public key token and if you display the properties for an assembly you can mark and copy the key to the clipboard:

Pk

Written by Nick Grattan

December 17, 2007 at 2:42 pm

Document Libraries: SPList and SPFolder.Delete Differences

with one comment

Removing items from a document library can be done in two different ways. Firstly, using SPList.Delete:

int iCount = spList.Items.Count;

for (int i = 0; i < iCount; i++)

{

    spList.Items[0].Delete();

}

This code will delete all the items/documents in all folders, but will leave the folders undeleted. Alternatively, you may write:

int iCount = spFolder.Files.Count;

for (int i = 0; i < iCount; i++)

{

    spFolder.Files[0].Delete();

}

This will delete the items/documents only in the folder represented by ‘spFolder’, and items/documents in other sub-folders will remain. The references to spList and spFolder can be obtained like this:

spList = currentWeb.Lists["MyDocumentLibrary"];

spFolder = currentWeb.Folders["MyDocumentLibrary"];

In this case, spFolder refers to the root folder in the document library.

 

 

 

 

 

 

 

 

Written by Nick Grattan

October 9, 2007 at 11:43 am

SPFolder / SPList: Deleting versus Recycling

with one comment

The following code shows how to remove all documents from a folder:

int iCount = spFolder.Files.Count;

for (int i = 0; i < iCount; i++)

{

    spFolder.Files[0].Delete();

}

Deleting documents with this code will delete permanently without using the recycle bin. To move the document to the recycle bin use the following code:

spFolder.Files[0].Recycle();

The SPItem class has a Recycle method as well as a Delete method and can be used in a similar way.

Written by Nick Grattan

October 9, 2007 at 11:13 am

Introducing the SharePoint object model

with 24 comments

As an alternative to programming against the SharePoint web services you can use the SharePoint object model. The object model can be used when the application will run on the server where SharePoint is installed (such as a console or WinForm application) or in assemblies that are run within a site (such as a Web Part).  

This sample shows how to display the sites and sub sites within a site collection as a hierarchy in a tree view control within a WinForm application.

Treeview

First, you will need to create a reference to “SharePoint.dll” assembly in your Visual Studio 2005 project. This is located at:

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.SharePoint.dll

A recursive function nicely solves the problem of loading the site hierachy into a tree view control. The method below is passed the tree node into which the site list will be loaded, and a SPWeb object representing the site whose sub-sites will be loaded:

       private void FillSubWeb(TreeNode tn, SPWeb webSite)

        {

            foreach (SPWeb theWeb in webSite.Webs)

            {

                TreeNode subTN = new TreeNode(theWeb.Name);

                tn.Nodes.Add(subTN);

                FillSubWeb(subTN, theWeb);

            }

        }

This method iterates over the “Webs” collection which returns each sub-site. A new TreeNode object is created with the site name. The node is added to the tree view  control. Lastly, the FillSubWeb method is called recursively, passing the TreeNode and theWeb object to load the sub-sites for the current site.

The following code kicks off the loading of the sites:

           

      SPSite site = new SPSite

           (“http://moss2007:8100/sites/intranet&rdquo;);

      SPWeb rootWeb = site.AllWebs[0];

 

      TreeNode tn = new TreeNode

            (“http://moss2007:8100/sites/intranet&rdquo;);

      tvSites.Nodes.Add(tn);

      FillSubWeb(tn, rootWeb);

The code gets a reference to the site collection from the URL, and then obtains a reference to the top-level web (site) for the site collection. A tree node is created and added to the tree view control to represent the site collection, and then the FillSubWeb method is called to start the recursive process.

 

Written by Nick Grattan

August 10, 2007 at 4:01 pm

Follow

Get every new post delivered to your Inbox.

Join 56 other followers