Thursday, 16 October 2014

SharePoint 2013 custom BCS Connector


SharePoint 2013 provides out of the box BCS connectors for Database, WCF, .Net and OData sources. If you need to connect to other form of data like a XML file or a file system then a custom BCS Connector has to be developed.

This blog post will explain the steps involved in creating a Custom BCS connector for SharePoint 2013 that connects to a XML file source. The steps involved  are
Developing Custom Connector Assembly
Creating the BCS model
Deploying the assembly and model
Creating external lists using custom connector

Developing Custom Connector Assembly
The customer connector assembly should have a class that implements the ISystemUtility interface from in Microsoft.BusinessData assembly. ISystemUtility interface provides functionality to execute operations against the external system. ExecuteStatic  method is the most important method within the interface where  we will be implementing CRUD actions for the custom connector.

The first parameter in ExecuStatic method is of type ImethodInstance and has a property called MethodInstanceType which indicates the type of method that is being called against the external content.  Finder MethodInstanceType  corresponds to retrieving  all items and SpecificFinder corresponds to retrieving a particular item.

The third parameter is an object array that has items that can be used with MethodInstanceType. The last item in the array is reserved for the return parameter.

Below is the execute static method for XML connector

public void ExecuteStatic(IMethodInstance mi,
            ILobSystemInstance si,
            object[] args,
            IExecutionContext context)
        {
              
           switch (mi.MethodInstanceType)
            {
                    //Single product view
               case MethodInstanceType.SpecificFinder:
                    int id = (int)args[0];
                    args[1] = GetProduct(id);
                    break;
                    //Product Listing
                case MethodInstanceType.Finder:
                    args[args.Length - 1] = GetProducts();
                     break;    
            }

        }
GetProducts method has the logic for retrieving all products from the XML file and GetProduct method has the logic for retrieving a particular product within the XML file. Sign the custom connector assembly with a strong name and generate the dll.

Creating the BCS model
The BCS model file can be created using a XML editor or using Visual Studio. The BCS model XML file has the below elements

LOB System
LOB System Instance
Entities

The Lob System element has the SystemUtilityTypeName property where we specify the fully qualified name of our custom connector assembly. Below is an example snippet of LOB System element
      <Properties>
        <Property Type="System.String" Name="SystemUtilityTypeName">
XMLFileConnectorG.Connector, XMLFileConnectorG, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3c36ccc14bfdf0d2
</Property>
      </Properties>

LObSystemInstance elements is where we can specify properties that can be used in custom connector assembly code. For example we can add a property to take the path of external XML source data file
<LobSystemInstances>
        <LobSystemInstance Name="ItemsData">
          <Properties>
            <Property Name="xmlfilepath" Type="System.String">c:\testfolder\products.xml</Property>
         </Properties>
        </LobSystemInstance>
      </LobSystemInstances>

Entity element section is where the identifier, fields and methods of our external content type is defined. Below is the snippet for an entity by name item with Finder and Specific Finder methods
<Entity Name="Item" EstimatedInstanceCount="1000" Version="1.0.0.0" Namespace="XMLFileConnectorG">
          <Identifiers>
            <Identifier Name="Id" TypeName="System.Int32" />
          </Identifiers>
          <Methods>
            <Method Name="ItemFind">
              <Parameters>
                <Parameter Name="id" Direction="In">
                  <TypeDescriptor Name="id" TypeName="System.Int32" IdentifierName="Id" />
                </Parameter>
                <Parameter Name="Item" Direction="Return">
                  <TypeDescriptor Name="Item" TypeName="Microsoft.BusinessData.Runtime.DynamicType">
                    <TypeDescriptors>
                      <TypeDescriptor Name="Id" TypeName="System.Int32" IdentifierName="Id" />
                      <TypeDescriptor Name="Title" TypeName="System.String"/>
                     <TypeDescriptor Name="Category" TypeName="System.String"/>
                    </TypeDescriptors>
                  </TypeDescriptor>
                </Parameter>
              </Parameters>
              <MethodInstances>
                <MethodInstance Type="SpecificFinder"
                                Name="ItemSpecificFinder"
                                Default="true"
                                ReturnTypeDescriptorLevel="0"
                                ReturnParameterName="Item">
                </MethodInstance>
              </MethodInstances>
            </Method>
            <Method Name="ItemDataFinder">
              <Parameters>
                <Parameter Name="Items" Direction="Return">
                  <TypeDescriptor TypeName="Microsoft.BusinessData.Runtime.DynamicType[]" IsCollection="true" Name="Items">
                    <TypeDescriptors>
                      <TypeDescriptor Name="Item" TypeName="Microsoft.BusinessData.Runtime.DynamicType">
                        <TypeDescriptors>
                          <TypeDescriptor Name="Id" TypeName="System.String" IdentifierName="Id" />
                          <TypeDescriptor Name="Title" TypeName="System.String"/>
                          <TypeDescriptor Name="Category" TypeName="System.String"/>
                          </TypeDescriptors>
                      </TypeDescriptor>
                    </TypeDescriptors>
                  </TypeDescriptor>
                </Parameter>
              </Parameters>
              <MethodInstances>
                <MethodInstance Type="Finder"
                                Name="ItemFinder"
                                Default="true"
                                ReturnTypeDescriptorLevel="0"
                                ReturnParameterName="Items">
                </MethodInstance>
              </MethodInstances>
            </Method>
          </Methods>
        </Entity>

Deploying the assembly and model
The custom BCS connector assembly has to be installed to Global Assembly cache on the SharePoint 2013 server and the BCS Connector model has to be imported before we can create content type from our model.

The custom connector assembly can be installed on the SharePoint server by using gacutil utility or by just dragging and dropping the assembly file to C:\windows\assemby folder.

To import the BCS model to SharePoint 2013 copy the BCS model file has to be copied to a location in SharePoint 2013 server and below steps have to be performed
1.       Logon to SharePoint 2013 central administration site

2.       Select Manage service application under Application Management

3.       Click BCS service application

4.       Click the Edit tab and click Import on BDC models ribbon

5.       In the Import BDC model page select the BCS your model file

6.       In File Type, select model option.

7.       In Advanced Settings, check Localized names, Properties, and Permissions check boxes.

8.       Click Import button.

The BCS model will be imported and the page will display all available models as shown below

 

 Clicking the model will show the external content types available in it.


 Clicking on the external content type will show details about the content type


Creating external lists using custom connector
Once we have installed the assembly and imported the BCS model, we can create external lists from the external content type by performing the below steps

1.       Navigate to the SharePoint site where the external site has to be created

2.       Click on Settings Icon from top left and click View Site Content menu

3.       On the Site Contents page click Add and app icon

4.       On the Your Apps page search for external list and click on External List from the result

5.       On the Add External List pop up give a name for the external list and select the external content type that was imported.

6.       External list will be created and content from the XML file will be populated