Consuming External OData Feeds with SharePoint BCS

I wrote an MSDN Magazine article, Consuming External OData Feeds with SharePoint BCS, which was published in April, 2011.  Using BCS, you can connect up to SQL databases and web services without writing any code, but if you have more exotic data sources, you can write C# code that can grab the data from anywhere you can get it.  Knowing how to write an assembly connector is an important skill for pro developers who need to work with BCS.  This article shows how to write a .NET Assembly Connector for BCS.  It uses as its data source an OData feed.  Of course, as you probably know, SharePoint 2010 out-of-the-box exposes lists as OData feeds.  The MSDN article does a neat trick – you write a .NET assembly connector that consumes an OData feed for a list that is on the same site.  While this, by itself, is not very useful, it means that it is super easy to walk through the process of writing a .NET assembly connector.

I write the article and the code for the 2010 Information Worker Demonstration and Evaluation Virtual Machine (RTM).  Some time ago, I wrote a blog post, How to Install and Activate the IW Demo/Evaluation Hyper-V Machine.

The MSDN article contains detailed instructions on how to create a read-only external content type that consumes an OData feed.  This is an interesting exercise, but advanced developers will want to create .NET assembly connectors that can create/read/update/delete records.  The procedures for doing all of that were too long for the MSDN magazine article, so of necessity, the article is limited to creating a read-only ECT.

However, I have recorded a screen-cast that walks through the entire process of creating a CRUD capable ECT.  It is 25 minutes long, so some day when you feel patient, you can follow along step-by-step-by-step, creating a CRUD capable ECT that consumes an OData feed.  Here is the video:

Walks through the process of creating an ,NET connector for an ECT that consumes an OData feed.

The procedure requires code for two source code modules: Customer.cs, and CustomerService.cs.

Here is the code for Customer.cs:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Contoso.Crm
{
    public partial class Customer
    {
        public string CustomerID { get; set; }
        public string CustomerName { get; set; }
        public int Age { get; set; }
    }
}

Here is the code for CustomerService.cs:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;

namespace Contoso.Crm
{
    public class CustomerService
    {
        public static Customer ReadCustomer(string customerID)
        {
            TeamSiteDataContext dc =
                new TeamSiteDataContext(
                    new Uri("http://intranet.contoso.com/_vti_bin/listdata.svc"));
            dc.Credentials = CredentialCache.DefaultNetworkCredentials;
            var customers =
                from c in dc.Customers
                where c.CustomerID == customerID
                select new Customer()
                {
                    CustomerID = c.CustomerID,
                    CustomerName = c.CustomerName,
                    Age = (int)c.Age,
                };
            return customers.FirstOrDefault();
        }

        public static IEnumerable<Customer> ReadCustomerList()
        {
            TeamSiteDataContext dc =
                new TeamSiteDataContext(
                    new Uri("http://intranet.contoso.com/_vti_bin/listdata.svc"));
            dc.Credentials = CredentialCache.DefaultNetworkCredentials;
            var customers =
                from c in dc.Customers
                select new Customer()
                {
                    CustomerID = c.CustomerID,
                    CustomerName = c.CustomerName,
                    Age = (int)c.Age,
                };
            return customers;
        }

        public static void UpdateCustomer(Customer customer)
        {
            TeamSiteDataContext dc =
                new TeamSiteDataContext(
                    new Uri("http://intranet.contoso.com/_vti_bin/listdata.svc"));
            dc.Credentials = CredentialCache.DefaultNetworkCredentials;
            var query =
                from c in dc.Customers
                where c.CustomerID == customer.CustomerID
                select new Customer()
                {
                    CustomerID = c.CustomerID,
                    CustomerName = c.CustomerName,
                    Age = (int)c.Age,
                };
            var customerToUpdate = query.FirstOrDefault();
            customerToUpdate.CustomerName = customer.CustomerName;
            customerToUpdate.Age = customer.Age;
            dc.UpdateObject(customerToUpdate);
            dc.SaveChanges();
        }

        public static void DeleteCustomer(string customerID)
        {
            TeamSiteDataContext dc =
                new TeamSiteDataContext(
                    new Uri("http://intranet.contoso.com/_vti_bin/listdata.svc"));
            dc.Credentials = CredentialCache.DefaultNetworkCredentials;
            var query =
                from c in dc.Customers
                where c.CustomerID == customerID
                select new Customer()
                {
                    CustomerID = c.CustomerID,
                    CustomerName = c.CustomerName,
                    Age = (int)c.Age,
                };
            var customerToDelete = query.FirstOrDefault();
            dc.DeleteObject(customerToDelete);
            dc.SaveChanges();

        }

        public static void CreateCustomer(Customer customer,
            out Customer returnedCustomer)
        {
            // create item
            TeamSiteDataContext dc =
                new TeamSiteDataContext(
                    new Uri("http://intranet.contoso.com/_vti_bin/listdata.svc"));
            dc.Credentials = CredentialCache.DefaultNetworkCredentials;
            CustomersItem newCustomer = new CustomersItem();
            newCustomer.CustomerID = customer.CustomerID;
            newCustomer.CustomerName = customer.CustomerName;
            newCustomer.Age = customer.Age;
            dc.AddToCustomers(newCustomer);
            dc.SaveChanges();
            returnedCustomer = customer;
        }
    }
}

!!!

4 Comments »

  1. BCS Read and Update Connector (OData) « Sladescross's Blog said,

    May 24, 2011 @ 7:33 am

    […] http://www.ericwhite.com/blog/2011/05/23/consuming-external-odata-feeds-with-sharepoint-bcs/   Leave a Comment LikeBe the first to like this post. […]

  2. Mauricio Dominguez said,

    June 2, 2011 @ 5:00 pm

    Hey Eric, I think your blog is really good. I’m developing my first Sharepoint 2010 services and I have a WCF WebService that recieves a parameter and returns a filtered list if data. I already have configured and deployed an external content type, configured it’s CRUD and created an external list.

    I’m trying to create a webpart that calls my custom method and shows this data somehow(preferablly using the already existing list) And i’m using a GenericInvoker to do so, but now I find the oblstacle of casting the results from “Object” to my External Content Type… I’m already out of ideas so I’d really apreciate your help….

    Thanke You

    Mauricio

  3. Windows Azure and Cloud Computing Posts for 7/15/2011+ - Windows Azure Blog said,

    July 20, 2011 @ 8:14 pm

    […] Consuming External OData Feeds with SharePoint BCS […]

  4. convertir pdf en word said,

    September 16, 2013 @ 9:17 pm

    Hello! Do you use Twitter? I’d like to follow you if that would
    be okay. I’m definitely enjoying your blog and look forward to
    new updates.

RSS feed for comments on this post · TrackBack URI

Leave a Comment