Monday, July 30, 2012

Determining the location of your SharePoint 2010 log files

If you're researching a problem with your SharePoint 2010 farm and wish to peruse the SharePoint log files, the standard location for these files is listed as follows:

 C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\LOGS

If the directory doesn't contain any files, this most likely indicates that your SharePoint Admin has configured the logs to be sent to another location in order to conserve hard drive space on the C: drive.  If the files have been moved, you can locate them via the following steps:
  1. Open SharePoint 2010 Central Administration
  2. Click on Monitoring
  3. Under Reporting, click on Configure diagnostic logging
  4. Scroll down to the Trace Log extension and locate the Path text box
The information contained in the Path text box is the location where your SharePoint log files are being written.

Thursday, July 19, 2012

Programatically set the initial selected node in an ASP.NET TreeView control

I just ran into a scenario in which I wanted to have the first node in a TreeView control selected the first time the user accesses the given page (i.e. the node is set when the page was initially loaded).  In order to make this work properly, I had to add two lines of code to my PageLoad event that performed the following actions:
  1. Set the selected node of the TreeView control
  2. Trigger the Treeview.SelectedNodeChanged event to simulate the user clicking on the given node
Here is a summarized sample of the code that I added to my PageLoad event that allowed me to simulate a user clicking on the first node when the page was initially loaded:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // Code that initializes the TreeView
        ...

        treeViewControl.Nodes[0].Select();
        treeViewControl_SelectedNodeChanged(this, EventArgs.Empty);
    }
}
If you'd like to select a certain node, my thought is that you could use the TreeView.FindNode method to locate a particular node in the list. In that case, your code would appear as follows:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // Code that initializes the TreeView
        ...

        treeViewControl.FindNode(PathOfNode).Select();
        treeViewControl_SelectedNodeChanged(this, EventArgs.Empty);
    }
}
Naturally, you will need to write some additional code to look up the path to your given node, but my hope is that this will give you some idea as to how this might be accomplished.

Tuesday, July 17, 2012

Programatically modify a SharePoint List Item

The following code sample code provides a means for being able to perform actions on a list item in one of your SharePoint List or Document Library.  In this particular instance, I'm reviewing a specific item in a Document Library and performing an action that is dependent on the Check Out status of the associated file:

using Microsoft.SharePoint;

...

Guid siteId = new Guid(...);
Guid webId = new Guid(...);
Guid listId = new Guid(...);
Guid listItemId = new Guid(...);

using (SPSite site = new SPSite(siteId))
{
    using (SPWeb web = site.OpenWeb(webId))
    {
        SPList list = web.Lists[listId];
        SPListItem listItem = list.Items[listItemId];

        web.AllowUnsafeUpdates = true;
        if (listItem.File.CheckOutType.Equals(SPFile.SPCheckOutType.None))
        {
            // Perform the action associated with the file being checked in...
        }
        else
        {
            // Perform the action associated with the file being checked out...
        }
        listItem.Update();
        web.AllowUnsafeUpdates = false;
    }
}

Tuesday, July 10, 2012

Adding an email link to a field contained in a GridView control

The following code sample provides a simple way to add a hyperlink to your GridView control that will launch the user's email client when the user clicks on the link.  In this case, you'll want to focus on the second BoundField control which creates the mailto hyperlink:

<asp:GridView ID="gridViewSiteAdmins" AutoGenerateColumns="false" runat="server"
    EnableModelValidation="True" >
    <Columns>
        <asp:BoundField HeaderText="Name" DataField="Name" />
        <asp:BoundField HeaderText="Email" DataField="Email" DataFormatString="<a href=mailto:{0}>{0}</a>" HtmlEncodeFormatString="false" />
    </Columns>
</asp:GridView>

By the way, there are other routes you can use to do this, but I thought I'd at least give you one that works well for me.

Wednesday, June 27, 2012

Create a Visual Web Part that displays the entire SharePoint site structure of a SharePoint web application

In the following code sample, I've created a Visual Web Part that will display the entire site structure contained under the parent SharePoint Web Application.  This web part will display all sites despite the fact that the given user may not have access to all of the sites beneath the structure.  Naturally, unauthorized users won't be able to access the site when he/she clicks on the link, but they will at least be aware of its existence and can contact the SharePoint Admin in order to request access.  For this web part, I've chosen to use a Tree View control for displaying the structure, but feel free to get creative if you like.  By the way, I've also added a method, SetCurrentNodeFont, here that can be used for highlighting the SharePoint site under which the web part is installed.  Last but not least, I've removed my error handling code in order to simplify things a bit so be sure to include or suffer the consequences...  


Here is the code:

ASCX File

<asp:TreeView ID="treeViewSiteNav" runat="server">
</asp:TreeView>


ASCX.CS File

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Administration;

protected void Page_Load(object sender, EventArgs e)
{
    treeViewSiteNav.Nodes.Clear();
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
        // Display the entire navigation structure of the web application
        SPSiteCollection sites = SPContext.Current.Site.WebApplication.Sites;
        foreach (SPSite currentSite in sites)
        {
            MapCurrentSiteCollection(currentSite.ID, currentSite.RootWeb.ID);
            currentSite.Dispose();
        }
    });
}


private void MapCurrentSiteCollection(Guid siteId, Guid webId)
{
    // Creating a new instance of the site because the currentSite is associated with the context of the
    // user whereas this new instance will run with elevated privileges
    using (SPSite site = new SPSite(siteId))
    {
        site.CatchAccessDeniedException = false;
        using (SPWeb currentWeb = site.OpenWeb(webId))
        {
            TreeNode siteNode = new TreeNode(currentWeb.Title, null, null, currentWeb.Url, "_self");
            SetCurrentNodeFont(ref siteNode, SPContext.Current.Web.ID, currentWeb.ID);
            treeViewSiteNav.Nodes.Add(siteNode);
            foreach (SPWeb web in currentWeb.Webs)
            {
                AddWebNodes(web, siteNode);
                web.Dispose();
            }
        }
    }
}

private void SetCurrentNodeFont(ref TreeNode node, Guid currentWebId, Guid evaluatedWebId)
{
    if (currentWebId == evaluatedWebId)
    {
        node.Text = Server.HtmlDecode(string.Format("<b>{0}</b>", node.Text));
    }
}

Friday, June 22, 2012

Remove special characters from a string using Regular Expression

If you're looking for an efficient way to remove special characters from a string, here is some sample code that utilizes a Regular Expression to do so:

using System.Text.RegularExpressions;
...
string inputString = "Sherman's Test #123";
string cleanOutputString = Regex.Replace(inputString,  @"[^A-Za-z0-9-_]", "");

This code sample will remove all characters except for alpha-numeric characters and "_".  If you would like to keep the empty characters/blank spaces, use this line instead:
string cleanOutputString = Regex.Replace(inputString,  @"[^A-Za-z0-9-_ ]", "");

Wednesday, June 20, 2012

Automatically activate a web or site scoped feature during site creation

I know of two good techniques for automatically activating a web or site scoped feature when a new SharePoint site is created and they are (1) if you're using a custom site definition, to insert a new <Feature> node within either the <SiteFeatures> or <WebFeatures> node of the ONET.xml file and (2) utilize a technique called Feature Stapling to attach your feature to a given site definition.

In both instances, you will need to know the ID, Title, and Scope of you feature.  These can be found by opening your feature's Feature.xml file and locating the appropriate attributes of the <Feature> node.  Here is a simplified example of what you might find in a sample Feature.xml file:

<?xml version="1.0" encoding="utf-8"?>
<Feature xmlns="..." Title="My Feature" Description="..." Id="b68c860b-b368-4e5f-ae06-dcfbfbd9c8da" ReceiverAssembly="..." Scope="Web"></Feature>


ONET.XML Update
This technique should only be used if your site is based on a custom site definition that you or your team created (i.e. that's the case if you have a custom ONET.xml file in your solution).  NOTE: You change will likely be overwritten with a service pack installation. With that said, the basic premise of this technique is to insert a new <Feature> node within either the <SiteFeatures> or <WebFeatures> node of the ONET.xml file which can be accomplished as follows:

  1. Open your ONET.xml file using Visual Studio or Notepad
  2. Locate the <SiteFeatures> or <WebFeatures> node depending on the scope of the feature
  3. Create a new <Feature> node and add the appropriate ID and Name attributes
  4. Save the changes
In this example, I will use the details from my sample feature:

<Project>
   <Configurations>
      <Configuration>
         <SiteFeatures />
         <WebFeatures>
            <Feature ID="b68c860b-b368-4e5f-ae06-dcfbfbd9c8da" Name="My Feature" />
         </WebFeatures>
      </Configuration>
   </Configurations>
</Project>

Feature Stapling
This technique is the only approach that I know of for automatically activating a feature on a standard SharePoint site template.  In this case, you will be creating a new Farm level feature that, when activated, will "staple" your feature to all sites that reference the specified template.  Here is an example of the "stapling" feature code that will be contained in a new Feature.xml file:

<?xml version="1.0" encoding="utf-8" ?>
<Feature Id="7ac7f1e9-1c6a-4ff0-a2bc-0d81e2360b70"
    Title="Feature Staple Sample"
    Description="Staple the associated feature(s) to the specified site definition(s)"
    Version="1.0.0.0"
    Hidden="FALSE"
    Scope="Farm"
    xmlns="http://schemas.microsoft.com/sharepoint/">
   <ElementManifests>
      <ElementManifest Location="staple.xml" />
   </ElementManifests>
</Feature>

and here is some sample code that will be contained in the references staple.xml file that will automatically launch the specified feature on the standard SharePoint Team Site template:

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <FeatureSiteTemplateAssociation Id="b68c860b-b368-4e5f-ae06-dcfbfbd9c8da" TemplateName="STS#0" />
</Elements>