Thursday, February 12, 2015

How to obtain a list of documents from a SharePoint library that were created X days ago using CSOM

In case you ever need to generate a list of documents contained in a SharePoint library that were created, say, 30 days ago or earlier, here is one way that you might go about doing that using CSOM:

using (ClientContext context = new ClientContext(@"https://webApplicationName/siteName"))
{
    context.Credentials = System.Net.CredentialCache.DefaultCredentials;
                    
    List documentsLibrary = context.Web.Lists.GetByTitle("Documents");
                    
    CamlQuery query = new CamlQuery();
    query.ViewXml = "<View><Query><Where><Leq><FieldRef Name='Created'/><Value Type='DateTime'><Today OffsetDays='-30' /></Value></Leq></Where></Query></View>";
         
    //CamlQuery query = CamlQuery.CreateAllItemsQuery();
    ListItemCollection expiringDocs = approvedDocumentsLibrary.GetItems(query);
                   
    context.Load(expiringDocs);
    context.ExecuteQuery();

    foreach (ListItem document in expiringDocs)
    {
        Console.WriteLine(string.Format("{0}", document["Title"]));
    }
}

You'll notice that the crux of the filtering operation is dependent on the XML contents contained in my CamlQuery object as follows:

<View><Query><Where><Leq><FieldRef Name='Created'/><Value Type='DateTime'><Today OffsetDays='-30' /></Value></Leq></Where></Query></View>

with the <Today> element being the key to this in order to take the current date and offsetting it by 30 days in the past.

CAML Queries always take a bit of trial and error in order to get them right so I hope this helps save you some time!

Tuesday, February 3, 2015

Possible solution for resolving a 409 Conflict Error when uploading a file to a SharePoint 2013 site using CSOM

I was just attempting to upload a file to one of my SharePoint 2013 sites using CSOM when I ran into a 409 Conflict error.  A simplified version of the code I was using is as follows:

using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Publishing;
using Microsoft.SharePoint.Client.Publishing.Navigation;
using Microsoft.SharePoint;
using System.IO;
...
using (ClientContext context = new ClientContext(@"https://webapplicationname/sitename"))
{
   context.Credentials = System.Net.CredentialCache.DefaultCredentials;
   using (FileStream fs = new FileStream(@"c:\docs\sample.doc", FileMode.Open))
   {
      Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, @"/Documents/sample.doc", fs, true);
   }
}

One major thing I'd like to highlight in the code above is that I was trying to set the context to reference a subsite that is located under the root site collection.  After a bit of experimentation, I actually stumbled onto the solution which is as follows:

using (ClientContext context = new ClientContext(@"https://webapplicationname"))
{
   context.Credentials = System.Net.CredentialCache.DefaultCredentials;
   using (FileStream fs = new FileStream(@"c:\docs\sample.doc", FileMode.Open))
   {
      Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, @"sitename/Documents/sample.doc", fs, true);
   }
}

In the code that worked, notice that I set the context to reference the root site collection and then used the second parameter in the SaveBinaryDirect method call to specify the relative path to the document library on the site in question.  At that point, the code worked perfectly and I was able to upload the document to the site's document library without any issues.

Hopefully, this may help solve your problem as well.

Thursday, January 15, 2015

Using jQuery Datatables on an ASP .NET GridView control

Lately, I've been using jQuery DataTables within several custom SharePoint apps that I've created; however, I've recently resurrected an ASP .NET Web Forms application that I was working on many moons ago and wanted to leverage jQuery DataTables on a GridView control that I'm using in this application.

What I discovered is that the crux of the matter when attempting to layer jQuery DataTables over a GridView control is that you need to format the HTML of the GridView so that it's recognizable by the DataTables code.  Essentially, your GridView needs to be formatted like so in order for it to be recognized:

<table>      <thead>           <tr>                <th></th>           </tr>      </thead>      <tbody>           <tr>                <td></td>           </tr>      </tbody> </table>

Here is what you can do at the very minimum to make this happen:

ASPX Page:

<script  type="text/javascript" language="javascript" src="Scripts/jquery-1.10.2.js"></script> <script type="text/javascript" language="javascript" src="Scripts/jquery.datatables.min.js"></script> <link type="text/css" href="Content/jquery.dataTables.min.css" rel="stylesheet" /> <div class="row">      <div class="col-md-4">               <asp:GridView ID="GridView1" runat="server" CssClass="gvdatatable" AutoGenerateColumns="true" OnPreRender="GridView1_PreRender">           </asp:GridView>      </div> </div> <script type="text/javascript">      $(document).ready(function () {            $('.gvdatatable').dataTable({});      }); </script>


ASPX Page Code-Behind:

protected void Page_Load(object sender, EventArgs e)
{
}

protected void GridView1_PreRender(object sender, EventArgs e)
{
     GridView1.DataSource = GetData();  //GetData is your method that you will use to obtain the data you're populating the GridView with

     GridView1.DataBind();

     if (GridView1.Rows.Count > 0)
     {
           //Replace the <td> with <th> and adds the scope attribute
           GridView1.UseAccessibleHeader = true;

          //Adds the <thead> and <tbody> elements required for DataTables to work
          GridView1.HeaderRow.TableSection = TableRowSection.TableHeader;

           //Adds the <tfoot> element required for DataTables to work
           GridView1.FooterRow.TableSection = TableRowSection.TableFooter;
      }
}

This code has been simplified from my original work, but I wanted to provide you with the bare bones minimum code that's needed so that you can get an idea of how to bolt this onto your existing project.  Hope this helps!

Tuesday, January 13, 2015

How to filter multiple metadata fields when using the SharePoint REST API

To place a filter on multiple metadata fields when you're leveraging the SharePoint REST API to extract information from a SharePoint list or document library, you can utilize the $filter operator; however, you'll need to be careful with how you structure the query or you'll get an error when submitting the request.

To combine these filters, you will need to utilize parentheses to seperate each unique filter operator.  To demonstrate this technique, I'm going to place two filters in my query that will be used to filter on two different metadata fields:

http://SharePointWebApp/SharePointSite/_api/web/lists/getbytitle('Documents')/items?$select=Name,LinkFilename&$filter=((Field1%20eq%20'FilterValueOnField1')%20and%20(Field2%20eq%20'FilterValueOnField2'))&$orderby=Name%20asc

Essentially, the basics of the REST call is that it will obtain the the Name and LinkFilename fields from documents contained in the default Documents library and order the results alphabetically. These results will be filtered so that only documents that have a value in Field1 equal to the specified value of FilterValueOnField1 and a value in Field2 equal to the specified value of FilterValueOnField2.

Thursday, January 8, 2015

Use jQuery to programmatically parse the text from an HTML element

If you ever run into a situation in which you need to programmatically remove the HTML tags from an HTML element in order to get the text contained within it, jQuery has a very nice option for this using the jQuery.text() method.  Here is a brutally simple example of how it works:

var htmlText = "<a href='#' target='_blank'>I need this text</a>";
var textINeed = $(htmlText).text();
alert(textINeed);

Naturally, real-life situations are going to be far more complex than this, but I thought this might get you pointed in the right direction.

Wednesday, August 20, 2014

Parsing a CSV file in C#

Every so often, I seem to run into a situation in which I need to parse a CSV file in order to read data into a system that I'm working with.  Rather than re-invent the wheel by writing my own parser, I tend to leverage the existing Microsoft.VisualBasic.TextFieldParser to do the work (yes, even though I'm using C#).  Here is some sample C# code that demonstrates how this can be used:


using Microsoft.VisualBasic;
using Microsoft.VisualBasic.FileIO;

...

TextFieldParser parser = new TextFieldParser(@"pathToCSVFile");
parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
parser.SetDelimiters(",");
while (!parser.EndOfData)
{
     string[] cols = parser.ReadFields();
     foreach (string col in cols)
     {
          Do something with the info in each field...
     }
}

To make a long story short, this existing Microsoft object will make your life a heck of a lot easier since it tends to handle most scenarios that would require special coding (i.e. properly handling quotes).  

Wednesday, June 11, 2014

How to obtain the PerformancePoint Dashboard Designer for SharePoint 2013

There is a lot of documentation floating around the web concerning the use of SharePoint 2013's PerformancePoint Dashboard Designer, but I had to do quite a lot of searching before I was able to determine exactly how you obtain it in the first place.  Here are the steps:

If you don't have a Business Intelligence Center site collection located on your farm, you will first need to create one via the following steps:
  1. Open Central Administration on your SharePoint 2013 environment
  2. Select Application Management
  3. Under Site Collections, select Create site collections
  4. Choose the appropriate web application where it should be installed
  5. Enter an appropriate Title and URL for your new site collection
  6. For Select experience version, select "2013"
  7. For Select a template, click on the Enterprise tab and select Business Intelligence Center
  8. Select an appropriate Primary and Secondary Site Collection Administrator
  9. Click OK
Once your Business Intelligence Center site collection is in place, use the following steps to obtain the PerformancePoint Dashboard Designer:

  1. Log on to the Business Intelligence Center site collection via your browser
  2. In the left navigation panel, select PerformancePoint Content

  3. Click on the tab that reads "PERFORMANCEPOINT"

  4. Click on the Dashboard Designer icon

  5. Click the Run button when prompted

Once the installation is complete, the Dashboard Designer will open and you can now begin working on all those other tutorials you found.