The Case
When querying the SharePoint CSOM API:s it is common that you want to fetch specific fields. If you have lots of queries going on toward SharePoint, you should find a way to avoid repetitive code (using the DRY principle) by creating a method that accepts a list of field names to be fetched.
Loading fields dynamically when using GetItems
Usually you will do the follow approach when loading items from a list based on a CAML Query and certain specific fields:
Web web = ctx.Web;
List list = ctx.Web.Lists.GetByTitle(_listNameVitalSignDefinitions);
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = "<View><RowLimit>500</RowLimit></View>";
ListItemCollection listItems = list.GetItems(camlQuery);
ctx.Load(listItems,
items => items.Include(
item => item.Id,
item => item["Title"],
item => item["ControlTime"],
item => item["Description1"]));
await ctx.ExecuteQueryAsync();
To avoid repetitive code, you can creating a generic method that accept the list of field names to be included when querying the GetItems method of the CSOM API. This method can be reused across your application, or even be centralized in your store of reusable components across different applications. In the code below, we have used App Only authentication, but this can of course be replaced with the necessary authentication method for your use case.
public static async Task<ListItemCollection> GetListItemsFromCamlQuery(string siteUrl, string listName,
string clientId, string clientSecret, string[] fieldNames, string camlQueryXmlString)
{
// Create the expression used to define the fields to be included
List<Expression<Func<ListItemCollection, object>>> fieldsToBeIncluded =
new List<Expression<Func<ListItemCollection, object>>>();
foreach (string s in fieldNames)
{
fieldsToBeIncluded.Add(items => items.Include(item => item[s]));
}
// Initialize the collection of list items
ListItemCollection listItems = null;
// Create a client context, in this case we use an App Only context
using (var ctx = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, clientId, clientSecret))
{
try
{
// Get the list item from the Price list library
Web web = ctx.Web;
List list = ctx.Web.Lists.GetByTitle(listName);
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = camlQueryXmlString;
listItems = list.GetItems(camlQuery);
ctx.Load(listItems, fieldsToBeIncluded.ToArray());
await ctx.ExecuteQueryAsync();
}
catch (Exception ex)
{
// TODO: Handle and/or log error
throw ex;
}
}
return listItems;
}