.net BC usergroup presentation downloads

Thanks to everyone who attended the .net BC event today on Microsoft SharePoint Server 2010 for the Microsoft ASP.NET Developer. It was great to see you all and from what I hear you liked the session :)

There are few resources that I have thrown into the PowerPoint which should be helpful when you get started with SharePoint development.

Also, the name of the tool I recommend for Visual Studio development is called CKSDEV and can be downloaded by going to Tools -> Extension Manager -> Online Gallery in your Visual Studio 2010.

When installed you will be able to access handy project templates from within Visual Studio.
If you have any questions, drop me a note here on my blog and I’ll share those questions and answers with other.

Also, to create visual web parts in sandbox, download the Visual Web Part Sandboxed into your Visual Studio extension manager using the same approach as CKSDEV.

And here is the link to the PowerPoint.
.net UG presentation download

Links to my books are on the right ;)

Enjoy!

Posted in Event material | Tagged , | Comments Off

How To: Restrict visibility of SharePoint 2010 lists and libraries

Most users define which lists and libraries are there on the site by accessing All Site Content link.
This is how most users see their lists and libraries of the default SharePoint 2010 team site.

As you add more lists and libraries to the site, you can actually hide them from this view. This can be achieved pragmatically or using PowerShell.

Here is the sample code which is used to show a hidden library:

using (SPSite site = new SPSite("http://[servername]"))
   {
          using (SPWeb web = site.OpenWeb())
          {
              SPList solutionGallery = web.Lists["Solution Gallery"];
              solutionGallery.Hidden = true;
              solutionGallery.Update();
          }
   }

If you’re wondering what this library we have just made visible – it’s a Sandbox Solutions library; the place where users upload and manage sandbox solutions.
After running this code, the library will be visible along with all of the other lists and libraries.
In your example, you might want to hide lists and libraries which are used for your core customizations. It’s important to understand that this will not make the list inaccessible to users, permission management will need to be applied on the library to actually prevent users from accessing the library.
This functionality is for purely cosmetic purposes to reduce clutter on your site.

Once hidden, the list will not be visible to many other office applications such as SharePoint Designer. By the way, if you’re running SharePoint Designer, you can hide/un-hide a list by accessing it’s properties from within SharePoint Designer and selecting Hide this list from views

Enjoy!

Posted in sharepoint 2010 | Tagged , | Comments Off

How To: Set granular restriction on SharePoint 2010 Sandbox Solutions uploads

SharePoint 2010 sandbox solutions allow individual site collection owners to manage limited access solutions without involving administrators.
To manage sandbox solutions you’ve got to have the following permissions:

  • Manage Web
  • Manage Sub webs
  • Add and Customize Pages

If you delegate site collection administrator permissions to anyone – they will have all of the above permissions. Which may not be what you intend. After all, the fact that someone can create pages and manage webs doesn’t mean you want them to be able to upload custom sandbox solutions. For example you may want to limit the number of sandbox solutions uploaded to the gallery or block the upload of sandbox solutions on that particular site collection and allow them on other site collections.

If you want to establish central solution management policies and restrict your users with more granular policies, you can attach an event receiver on the solution gallery which holds all of the sandbox solutions.

Even though you access the solution gallery using the Site Settings page, as shown above, it’s just a specialized document library, which in fact has a Document Library as it’s base template.

We’ll start with creating a new Visual Studio 2010 SharePoint Project of Event Receiver solution template. You can use another project template as long as an event receiver is added to them later.
Ensure the project is a farm solution and from the receiver configuration wizard pick the options as shown below:

As you can see, our event receiver will run on new items (sandbox solution) being added, this way we can choose whether we allow a particular item or not.
Also, we have selected a custom list as our list template since Visual Studio doesn’t allow us to pick solution gallery by default. That’s ok, we’ll change this in a moment.

Once the project has been created, open the Elements.xml configuration file of the event receiver and set the ListTemplateID attribute value to 121, which is the ID of the solution gallery. This way our receiver will run events on the solution gallery and not on the custom list template as we’ve chosen earlier in the wizard.

Lastly, we need to write some code which represents our new solution upload policy. The code will go right into the event receiver class.
In my case, the code blocks the upload of any sandbox solution and shows a custom page to a user:

public override void ItemAdding(SPItemEventProperties properties)
       {
           base.ItemAdding(properties);
           properties.Cancel = true;
           properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
           properties.RedirectUrl = "_layouts/Project/SomeCustomErrorPage.aspx";
       }

Remember, since our custom project is a farm solution, it will run this code in each site collection. So with the code above, no-one will be able to upload sandbox solutions; you may want to be more specific with your custom policy.
That’s it, now you can deploy the event receiver project as you normally would.
To test, upload any sandbox solution into the solution gallery to get a custom or generic error message.

You’ll find more handy tips like this in my SharePoint 2010 dev book.

Enjoy!

Posted in sharepoint 2010 | Tagged , | Comments Off

How To: Extend SharePoint 2010 third party or legacy webparts in your solution

Since the title of this post doesn’t really do justice, let’s take a look at a few scenarios.

Scenario 1. You have a third party webpart and would like to alter it’s execution flow as much as it permits through public properties and methods.

Scenario 2. You have a legacy webpart and no source code; you would like to use a legacy webpart as a main part and add a few extra components and render them all as one webpart.

Since each SharePoint webpart inherits from System.Web.UI.WebControls.WebParts, requiring it to have a default constructor, you can render a webpart as part of another webpart in few simple steps.

We’ll start with creating a new Visual Studio 2010 SharePoint Solution and for template choose a Visual WebPart Project. Let’s call this project HostWebpart so it’s clear as we go along.

We’ll also need another webpart to which will be hosted within HostWebpart. Whether it’s one of your own webparts or a third party webpart, it doesn’t matter. You can download a free webpart you can use for testing from codeplex. This web part will be hosted within out HostWebpart. Well call it a Hosted Part.

Depending on the complexity of your Hosted Part, if it uses external resources such as CSS and controls, you will need to deploy the WSP first so all of the dependencies are in place.

Next, navigate to your portal and add a Hosted Part to the page. Once added, export the webpart declaration as shown below:

Save the file and open it in Notepad. The top part will show you the assembly name and the type we’ll reference later.
Here is the sample I have exported.

<webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="Microsoft.SharePoint.Publishing.
           WebControls.ContentByQueryWebPart,
           Microsoft.SharePoint.Publishing, Version=14.0.0.0,
           Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

Since in my case, I’ve used out-of-the-box webpart, the Content by Query Webpart, my assembly is Microsoft.SharePoint.Publishing and the type name is Microsoft.SharePoint.Publishing. WebControls.ContentByQueryWebPart. In your case, remember those items, we’ll reference them in just a bit.

In your HostWebpart Visual Studio project, reference the assembly in the DLL References. Even though our HostWebpart is already deployed, we need a DLL reference so we can create an instance of it in the HostWebpart.

Now we can create an instance of the Hosted Part right within our Visual WebPart project (the HostWebpart). Open the code behind of the user control for your Visual WebPart (VisualWebPart1UserControl.ascx).

In the Page_Load event, create an instance of your Hosted Part by calling it by type you’ve recorded earlier, in my case I would define my Hosted Part like this:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

namespace VisualWebPartProject1.VisualWebPart1
{
    public partial class VisualWebPart1UserControl : UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart cqwp =
                new Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart();

            cqwp.ChromeType = PartChromeType.None;
            // any other public properties or methods can be called in here
            this.Controls.Add(cqwp);
        }
    }
}

Notice how I set the ChromeType property of the Content by Query Webpart. Well, this will ensure the border around it is not displayed and it will appear as it’s part of the HostWebpart.
In the actual ASCX control representing the Visual Webpart, you can add any elements you require, they will all render along with the Content by Query Webpart just as they were a single webpart.
Notice how we added our Content by Query Webpart to the main set controls:

this.Controls.Add(cqwp);

Well, if you like, you can add it to another control such as a panel or a repeater etc. This way you can control it’s rendering if required. Just add the panel or another component to your Visual Werbpart and then you can start adding Controls to it.

Of course, in this approach you’re limited to public properties of the Hosted Part in terms of altering its execution flow; but in many scenarios that’s all you need.

Try it out with a third party webpart!

Posted in sharepoint, sharepoint 2010 | Comments Off

How To: Toggle SharePoint 2010 list and library view properties

SharePoint allows users to add views of lists and libraries on the any page within your site.
When added, users can toggle various properties of the view just as it was a web part. You can change the appearance settings, the layout etc.

If I was to provision this view pragmatically using a page schema, I wouldn’t have been even able to access half of those properties. For example, when you add a Document Library view to the page using schema XML, the markup looks like this:

<View List="MyDocumentLibrary" BaseViewID="0"
  WebPartZoneID="Zone1" />

There are only a few properties available when declaring a view but you can’t change the chrome type, for example. With the chrome type visible, users will be able to see some elements of the view I may want to hide.

Let’s take a look at how you can access those properties with a feature receiver once the view is provisioned to the page.

I assume you’re provisioning a new page using a SharePoint feature, which means you can reuse the same feature and add a feature receiver to it with the logic which will handle modifying the properties.

If you have an existing page and not using a receiver, you can run a code below (with few small mods) in a console application to get the same result.

If you’re interested how to do the same using PowerShell, you got to check out my new PowerShell book

// I assume you get the web either from context or site
PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);

foreach (SPListItem pageListItem in publishingWeb.PagesList.Items)
{
    PublishingPage page = PublishingPage.GetPublishingPage(pageListItem);
    if (page.Title.Equals("Page Title Im interested in",
        StringComparison.InvariantCultureIgnoreCase))
    {
        page.CheckOut();
        SPLimitedWebPartManager webPartManager =
           web.GetLimitedWebPartManager(page.Url,
System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
        if (webPartManager.WebParts.Count > 0)
        {
         // I assume your page has the view only and not other webparts
          XsltListViewWebPart webpart =
             webPartManager.WebParts[0] as XsltListViewWebPart;
          webpart.ChromeType =
             System.Web.UI.WebControls.WebParts.PartChromeType.None;
          webPartManager.SaveChanges(webpart);
        }
        page.Update();
        page.CheckIn("Updated by the system);
    }
}

Basically, we get a hold of the page and access it’s web part manager object, which contains all the web parts for the page. Then, we get a hold of the web part with an index 0; in your case, if you have a page with several web parts, you’d want to select the web part by its title or type.
Once you’ve got the right web part, we set it’s properties as required; in my case we’re turning off the chrome for the web part.
That’s it, the page is then checked in …

Enjoy!

Posted in sharepoint | Tagged , , , , | Comments Off

How To: Hide SharePoint 2010 fields in display, edit and new forms

SharePoint 2010 allows you to choose which fields in your lists will be displayed in the New, Edit, View forms and which ones aren’t.
Even though the field will be available to the object model in the code behind, it won’t be displayed in forms which is a great way to protect users from themselves for system and reserved fields.

Your changes would be defined in the schema.xml of the list definition.
Below we have a Number field, called MyField which will not be visible in a view form (ShowInDisplayForm), edit form (ShowInEditForm), new item form (ShowInNewForm), not show in the list settings page (ShowInListSettings), not show in the version history view (ShowInVersionHistory).

<Field ID="{C1EFE1C4-FF59-4D10-975E-905B6D61350F}"
Type="Number"
Name="MyField"
DisplayName="MyField"
SourceID="http://schemas.microsoft.com/sharepoint/v3"
StaticName="MyField"
ShowInDisplayForm="FALSE"
ShowInEditForm="FALSE"
ShowInNewForm="FALSE"
ShowInListSettings="FALSE"
ShowInVersionHistory="FALSE">
</Field>

Any combination of above works too of course.
If you found this post useful, check out more of the handy tips like this in my SharePoint 2010 developer book.

Enjoy!

Posted in sharepoint | Tagged , , , | Comments Off

How To: Customize SharePoint 2010 out-of-the-box workflow initiation form

SharePoint allows you to create instances of out-of-the-box workflows anywhere on the site.
Once those instances are created, when the workflow gets initialized on the item – your users get to fill in any of the required initiation parameters on the workflow initiation form. For out-of-the-box workflows such as Approval Workflow or Collect Feedback workflow, those are InfoPath forms.
There is a lot you can do with InfoPath forms, but there is a lot you can’t!
For example, a simple action of grabbing the value from a query string and rendering it to the user is just not available for workflow sourced InfoPath forms.
In fact, many standard InfoPath form features become unavailable as soon as your form is an initiation or association form for a workflow.

In my scenario, I have an approval workflow and I would like to display a link on the workflow form which will allow my users to view the source library where the item is located; the item which workflow runs on.

Now, in my case, the workflow Initiation form already passes a query string variable called Source which holds the link to a library. Although my scenario is simpler, you can use the approach outlined below for more complex scenarios.

I assume you already have an out-of-the-box approval workflow attached to one of the libraries. Run the workflow on the item to see a page similar to below:

As you can see, the InfoPath form in this page is hosted within IniWrkflIP.aspx, which is an out-of-the-box page we can’t modify.
We’ll create a new page and bind it to our workflow in just a moment.
Navigate to C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS and find IniWrkflIP.aspx.
Make a copy of the file and call it IniWrkflIP_Modified.aspx, or whatever name you need, just don’t forget it.
Now, you can open up that page and start customizing it.
You can make virtually any changes to the page as long as you don’t try to convert some of it’s core properties, such as a page type.

You will notice that the page has the following two core components defined:

<InfoPath:XmlFormView id="XmlFormControl" runat="server"
  style="width:100%;margin-left:20px;" />
<SharePoint:FormDigest runat=server/>

If you like to deploy new workflow initiation form created in Visual Studio, instead of using a copy of the existing page, ensure you declare the InfoPath form view from above and any references that this view needs. Apart from that, you can customize the page however you need it.

In my case I will add the following link to the item folder, defined right under the :

<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">

The link will be defined based on the query string value as follows:

<%
if (List != null)
{
%> <a target="_new"  href="<% SPHttpUtility.AddQuote(
 SPHttpUtility.UrlPathEncode(Page.Request.QueryString["Source"],true),
  Response.Output);%>">View items in folder</A>
}
%>

That’s it, I’ll save the file. Now it’s time to associate this new initiation page to the approval workflow on my site.
Open SharePoint Designer 2010 and open up the site where you attached the workflow to a list.
Under Site Objects click All Files, and in there navigate to click _catalogs/wfpub.
This is where all of the workflow templates reside for this site.
In our case, we’ll pick a Approval – SharePoint 2010. In there you will see several files including the InfoPath forms themselves.
Open the workflow configuration file as shown below, select Edit to edit the file:

In this file, you will find many of the initiation variables for out-of-the-box approval workflow, including the workflow initiation form defined as below:

<Initiation URL="_layouts/IniWrkflIP.aspx">

Change the name of the form from IniWrkflIP.aspx to IniWrkflIP_Modified.aspx, if that’s the name you specified for your page earlier.
Save the configuration file. That’s it, the workflow will now use your newly created initiation page.
Since you changed the template for approval workflow on the site, this is the version of the workflow that all new instances on the site will inherit. Templates for other sites remain intact.
You can also choose to make a copy of the approval workflow and localize your change even more.

Now when you run an instance of the approval workflow on the library where you modified the initiation form, your custom logic will execute as expected. In my case, it’ll show a link to a source library of the workflow item.

If you liked this post, you’re in for a treat when you read my SP2010 developer book.

Enjoy!

Posted in sharepoint 2010 | Tagged , | Comments Off

How To: Report which documents are on hold and hold details in SharePoint 2010

SharePoint 2010 allows you to put documents inside your Record Center on hold; which will exempt those documents from retention policies and workflows. This is a handy feature in case you’re in the middle of an audit and want to pause standard lifecycle of selected documents.

When putting a document on hold – you can pick a type of hold which can be created using Site Actions -> Site Settings -> Holds list. By using a context menu, then, you select a hold type, and an optional comment related to the hold you’re applying to the document.

Now that the document is on hold – all of the policies apply, but how do you report of documents and types of hold that was applied to them.

First, let’s see how you can get to the basics …
To see the URLs of the items on a particular type of hold – you’d want to follow the steps below:

1. From the record center navigate to Site Actions -> Site Settings 

2. Under Holds and eDiscovery click Hold Reports.
You will see a document library with a list of excel files
 representing each type of hold.
Those excel files are generated on a daily basis by default
 by a Hold timer job.
You can run the time job on demand or decrease an interval
 of how often the time job runs.

3. Pick an excel file representing a particular type of hold.

4. Switch to Items on Hold sheet in the excel report and
  see the URLs of items that are on that particular type of hold.

Now, above report doesn’t give us the comments that users enter when the document is on hold.
As it turns out, when document is put on hold – SharePoint 2010 also records an audit event, so you can extract event data (such as type of hold and associated comments) by running an audit report. This is not so widely documented, so let’s see what’s involved.

1. From the records center, click Site Actions -> Site Settings.
2. Click Audit log Reports as shown below:
3. Click run a "Custom Report"
4. Provide the location (document library) to save this on demand report
5. From the list of events, pick Custom Events only
6. Pick any other filtering parameters such as a date range or
  a user name to zero down the report on.
7. Click OK, the report will render and you will be offered to download it.
8. Open an excel report and select the Report Data sheet in excel.
9. Filter the report to have Source = Hold
10. You will also see the type of hold and user comments in the EventData column.
Thats`s where you get all of the comments and types of hold applied.

The second option is not widely described online so I often get asked whether this is even possible … it is, and now you know how.

Enjoy!

Posted in sharepoint, sharepoint 2010 | Tagged , | Comments Off

How To: Automatically add All Authenticated Users to SharePoint security group

When performing SharePoint 2010 enterprise solution deployment with Visual Studio, you’re likely to pre-create many of your solution artifacts such as pages with the right web parts on them etc. Security groups is not an exception. Recently I needed to pre-populate my custom security groups with All Authenticated Users.

You can add an All Authenticated Users reserved “user” to any security group which means that anyone who is authenticated will have access to the resource that this group governs with the permissions levels you choose to give it.

Below I’ll demonstrate how we can create a custom security group with the Read permission level and how that group will automatically have All Authenticated Users reserved “user” added to it.

The code below can run as a part of the feature receiver or a console application or PowerShell (obviously for PowerShell you will need to convert this code to a similarly-looking commands).
In my case, I used feature receiver with the following in FeatureActivated event:

SPWeb web = properties.Parent as SPWeb;
permissionLevel = "Read";
web.SiteGroups.Add("My Special Group", owner, owner, "My Category");
SPRoleAssignment roleAssignment = new SPRoleAssignment(web.SiteGroups["My Special Group"]);
roleAssignment.RoleDefinitionBindings.Add(web.RoleDefinitions[permissionLevel]);
web.RoleAssignments.Add(roleAssignment);
web.Update();
// "c:0(.s|true" = All authenticated users
web.SiteGroups["My Special Group"].AddUser("c:0(.s|true", string.Empty,
 string.Empty, string.Empty);

That’s it, the reserved user id c:0(.s|true, will resolve to All Authenticated Users when the feature is activated.

If you found this tip handy, as they say, there is more where that came from; it’s in my book here, where you’ll find development approaches is a cookbook style for your everyday SharePoint 2010 development.

Enjoy!

Posted in sharepoint 2010 | Tagged , | Comments Off

How To: Hide SharePoint 2010 root node from the top menu

When customizing SharePoint 2010 UI, one of the most common things you come across is to customizing the navigation control.
In this post, I’d like to share one of the approaches discussed in my SharePoint 2010 branding book on working with SharePoint 2010 navigation.
As you know, for SharePoint Publishing site template you can choose which links on the top navigation you want to show or hide, however, you don’t get to choose whether you want to display the root node representing a root site.
So you end up with the root node showing in your top menu:

If you take a look at the masterpage for your publishing site, here is how navigation control gets defined:

<SharePoint:AspMenu
  ID="TopNavigationMenuV4"
  Runat="server"
  EnableViewState="false"
  DataSourceID="topSiteMap"
  AccessKey="<%$Resources:wss,navigation_accesskey%>"
  UseSimpleRendering="true"
  UseSeparateCss="false"
  Orientation="Horizontal"
  StaticDisplayLevels="2"
  MaximumDynamicDisplayLevels="1"
  SkipLinkText=""
  CssClass="s4-tn"/>

As you can see it takes the collection of items to display from the topSiteMap data source. In fact any custom or 3rd party menu control could consume existing data source. You can get a hold of the underlying CSS structure and hide the root item that way, but there is way more elegant approach to control the root node.
Below you see the delegate control representing the data source for our navigation, you can find it by its ID topSiteMap.

<SharePoint:DelegateControl runat="server" ControlId="TopNavigationDataSource"
  Id="topNavigationDelegate">
	<Template_Controls>
	<asp:SiteMapDataSource
	  ShowStartingNode="False"
	  SiteMapProvider="SPNavigationProvider"
	  id="topSiteMap"
	  runat="server"
	  StartingNodeUrl="sid:1002"/>
	</Template_Controls>
</SharePoint:DelegateControl>

As you can see there is a property called ShowStartingNode which controls whether the root node is displayed or not. You can change the value of the property for your case using SharePoint Designer and you’ll quickly realize that nothing changes.

The reason why nothing changes and the root node is still displayed on the site is because the delegate control in the masterpage will be replaced by the actual control definition since it’s just a delegate. If you wonder when this control is replaced and how … out-of-the-box publishing site templates activate the feature called Navigation located in the 14 hive:

In the feature definition you can see that the control gets the property values as shown below with all the properties set right from the feature, including the ShowStartingNode being set to true

<Control
Sequence="50"
Id="TopNavigationDataSource"
ControlClass="Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapDataSourceSwitch"
ControlAssembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0,
    Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Property Name="ID">topSiteMap</Property>
<Property Name="SiteMapProvider">GlobalNavigation</Property>
<Property Name="EnableViewState">false</Property>
<Property Name="StartFromCurrentNode">true</Property>
<Property Name="ShowStartingNode">true</Property>
<Property Name="TreatStartingNodeAsCurrent">true</Property>
<Property Name="TrimNonCurrentTypes">Heading</Property>
</Control>

There are few ways to overwrite this setting:

1. Activate a custom feature which will reset the value of the delegate back to what you’d like to be.
2. Or, just get rid of the delegate wrapper code altogether and set the values of your desired properties right inside a masterpage.

This means that you would access your masterpage and remove the datasource delegate wrapper code:

<SharePoint:DelegateControl runat="server" ControlId="TopNavigationDataSource"
  Id="topNavigationDelegate">
	<Template_Controls>
	</Template_Controls>
</SharePoint:DelegateControl>

Leaving only the actual data source control definition with any properties you desire, as shown below:

<asp:SiteMapDataSource
  ShowStartingNode="False"
  SiteMapProvider="CombinedNavSiteMapProvider"
  id="topSiteMap"
  runat="server"/>

Now when you save the masterpage, all of your navigation property choices will be picked up by whatever navigation control you’re using, including out-of-the-box SharePoint:AspMenu control.

Enjoy!

Posted in sharepoint 2010 | Tagged , , , | Comments Off