Building a .NET Connectivity Assembly Share Point 2010

Building a .NET Connectivity Assembly
You’ve seen how to connect to a business system using SharePoint Designer. The wizards make it simple to connect to SQL Server databases or appropriately designed WCF services. But what happens if you want to connect to something a bit more exotic? The answer is to create a .NET connectivity assembly. By creating a connectivity assembly, you can write code to handle any of the operation stereotypes supported by the BDC service. As mentioned earlier, BDC itself doesn’t read or write to the external data store; it simply delegates to an appropriate endpoint. By creating a connectivity assembly, you can effectively create custom endpoints to do whatever is appropriate for your application.

Pluggable Connector Framework
As briefly covered earlier in the section “Connector Framework,” BCS makes connections to external systems via a pluggable connector framework. It is therefore possible to create custom connectors to interface with external systems. While creating custom connectors is beyond the scope of this chapter, it’s worthwhile for you to know the differences between creating a custom connector and using a connectivity assembly.

Connectivity assemblies encapsulate an entire data access model. In the preceding section, we worked through configuring the metadata for the database connector; with connectivity assemblies, such configuration isn’t required since the metadata is installed with the connectivity assembly. Naturally, this lack of configurability can also be considered a drawback where the APIs for the external data store are likely to change frequently.

When you’re building custom connectors, you should be aware of some installation considerations. Connector assemblies must be manually installed in the Global Assembly Cache (GAC) on each server or rich client that intends to use the connector. By contrast, a connectivity assembly is stored within the BDC data store and is therefore automatically available to the BDC service on every server. Where the assembly is required by a rich-client interface, it is seamlessly installed via ClickOnce.

Business Data Connectivity Model Project
From our demonstration scenario, we require the functionality to attach product information retrieved from Internet search results to our competitive analysis reports. Of course, we could achieve this result by using a web browser and simply cutting and pasting the URL into a text field, but in the age of the mash-up, switching between applications in such a fashion would almost certainly lead to a disciplinary hearing of the International Association of Mash-up Artists—not to mention the fact that it would deprive us of the opportunity to explore Business Data Connectivity Model projects in Visual Studio 2010.

Create a New Project in Visual Studio 2010
To create a new Business Data Connectivity Model project, take the following steps:

  1. Open Visual Studio 2010. Choose File | New | Project.
  2. In the New Project window, select SharePoint in the left pane and Business Data Connectivity Model in the middle pane, as illustrated next. In the Name text field, type BingConnectivity.
  3. Create a New Project in Visual Studio 2010

  4. In the SharePoint Customization Wizard, select your local server for use when debugging.
  5. Click Finish to create the project. A new project will be created containing a BDC Model and a single sample entity, as shown in Figure.

The Visual Studio 2010 design surface for creating connectivity assemblies includes a number of specific tools. First, the entity view, shown in the middle of the page in Figure, lets you see all of the entities defined in your data source and the identifiers and methods defined on them. By clicking a method or identifier in the entity view, the BDC Method Details pane, shown below the entity view in the figure, is populated with details about the methods and identifiers defined in the entity. Finally, the upper-right pane in Figure is the BDC Explorer pane. This control presents a hierarchical view of your BDC model.

Figure:The Business Data Connectivity Model design surface

Figure:The Business Data Connectivity Model design surface

Create a Custom Entity Service Object
Before we jump into creating a new Entity Service object, it’s worth discussing what an Entity Service object is and how it relates to the rest of the items in our model. A BDC model project consists of three things:

  • A BDCM file that contains the configuration metadata for the connection
  • An Entity Service class that contains the methods that will be the endpoints of the operations defined in the metadata
  • An Entity class that contains the data to be processed by the Entity Service methods.

To relate this back to the connection we made earlier via SharePoint Designer, the BDCM file contains the configuration details that we entered in the Operations Design View of the External Content Type. The Entity Service object is the equivalent of the ADO. NET provider for SQL Server and the Entity class represents a row of data.

Now that you have a clear understanding of the purpose of the Entity Service object, we can move on to add the code required to support our data source.

  1. Since the search service is accessed via a web service, we need to add a new service reference. Choose Project | Add Service Reference.
  2. In the Add Service Reference dialog, enter.
  3. Click Go to download the service WSDL.
  4. Set the Namespace to Microsoft.Bing, and then click OK to create proxy classes for the service, as shown here:

Create a Custom Entity Service Object

Define a Method to Support the Finder Stereotype
Our next step is to implement methods that will be called by BCS clients to interact with the data source. In our demonstration scenario, we need to be able to query the data source using a wildcard query and retrieve a single specific result.

First of all, let’s take a look at the query method. You’ll remember from earlier examples that the operation for retrieving a list of data is referenced using the Finder stereotype. We’ll start by creating a new method for this stereotype.

  1. In the Entity viewer in Visual Studio, delete the default Entity1 object, and then drag a new Entity from the toolbox onto the design surface. Change the Entity name to WebResult.
  2. In the BDC Methods Details pane, click <Add a Method> to create a new method. From the drop-down that appears, select Create Finder Method. This will automatically add a method named ReadList.
  3. Since our Finder method needs to be able to perform wildcard searches, we need to add a wildcard filter. We’re effectively performing the same configuration that we did earlier when we set up a search filter on the Model External Content Type— you’ll no doubt recognize some of the configuration objects that we’re dealing with. To add a new filter, we first need a parameter to which we can attach the filter. We’ll add a new query parameter to the ReadList method. Expand the parameters node in the BDC Method Details pane, and then click Add a Parameter. Select Create A Parameter to add a new parameter to the method. You’ll notice that although the default parameter name is selected in the BDC Method Details pane, it’s not possible to overtype it with a new value. To add a new value, we need to use the Properties pane, as shown next. Type query for the new parameter name.
  4. Define a Method to Support the Finder Stereotype

  5. With this new parameter in place, we’re now free to add a new filter. Under the Filter Descriptors node, click <Add a Filter Descriptor>, and then select Create a Filter Descriptor. As before, use the Properties pane to change the Name to Search Filter and the Type to Wildcard. To make this filter the default, we need to add an additional property. Click the ellipsis next to Custom Properties in the Propertiespane to add another property. Type IsDefault for the Name, System.Boolean for the Type, and true for the Value.
  6. Now that we have a filter, we need to associate it with our ReadList method. We can do this by selecting an associated type description. You’ll notice in the BDC Method Details pane that each parameter has a type descriptor attached. A type descriptor is metadata that defines the type of the parameter as well as a number of properties that control how the type should be handled, such as whether the type is an identifier or should be read-only. When we added our additional parameter to the ReadList method, a new type descriptor was automatically created. We need to attach our Search Filter to this type. From the BDC Explorer pane, expand the ReadList node and the query node beneath it. Select the queryTypeDescriptor node to define the properties of the parameter. First, let’s change the name to something more succinct: In the Properties pane, change the Name to simply query. To attach the filter to this type, select the filter name (Search Filter) from the drop-down list next to the Associated Filter property, as illustrated next:

Define a Method to Support the Finder Stereotype

Define a Method to Support the SpecificFinder Stereotype With our Finder operation in place, the next thing we need to add is a SpecificFinder operation to allow clients to retrieve a single specific entity.

  1. Follow steps 2 and 3 above to add a new method, but this time select Create a SpecificFinder in the BDC Method Details pane. By default, the new method will be named ReadItem.
  2. Since this method returns only a single item, we don’t need to create any filters. However, we do need to add a parameter that will uniquely identify the item to be returned. Since the results will consist of web pages, the most sensible identifier is the URL. Follow steps 4 and 5 above to add a new parameter named itemUrl.
  3. A new Type Descriptor of itemUrlTypeDescriptor is added. For the sake of brevity. rename this as itemUrl using the BDC Explorer:
  4. Define a Method to Support the SpecificFinder Stereotype

  5. Before we move on to add the code to support these new methods, we need to add one more piece of metadata to the model: we need to declare our identifier. Rightclick the WebResult entity and select Add | Identifier, as shown next. Change the default name to itemUrl.
  6. web result

  7. With this identifier created, we can now update the metadata for the itemUrl descriptor that we’re using to define the parameter for the ReadItem method. In the BDC Explorer pane, select the itemUrl type descriptor (ReadItem | itemUrl | itemUrl), and then, in the Properties pane, change the Identifier property to itemUrl.

Now that we have the metadata in place for our model, we can start fleshing out our ReadList and ReadItem methods.

  1. Save the BDC model, and then switch to the Solution Explorer pane in Visual Studio. You’ll notice that a WebResultService.cs file has been added. Open this file, and you can see that as we’ve been making changes to the model, Visual Studio has automatically created stub methods with the appropriate parameters for us. Since we don’t need them, delete the Entity1.cs and Entity1Service.cs files that were added to the project by default.
  2. In the WebResultService class, add the following code:
  3. using System.Collections.Generic; using System.Linq; using System.ServiceModel.Channels; using System.ServiceModel; using BingConnectivity.Microsoft.Bing; namespace BingConnectivity.BdcModel1 { public partial class WebResultService { public static IEnumerable<string> ReadList(string query) { //We can’t perform a web search with no query if (!string.IsNullOrEmpty(query)) { //Get an instance of the Bing proxy class BingPortTypeClient client; SearchRequest request = GetRequestProxy(out client); //Setup the request parameters request.Query = query; //Execute the search SearchResponse response = client.Search(request); //Shape the results to suit our requirements var results = from r in response.Web.Results select r.Url; return results; } else { return null; } } public static string ReadItem(string itemUrl) { if (!string.IsNullOrEmpty(itemUrl)) { BingPortTypeClient client; SearchRequest request = GetRequestProxy(out client);
    request.Query = itemUrl; SearchResponse response = client.Search(request); //Since urls are globally unique this query will //only return one result return response.Web.Results.Single().Url; }
    { return null;
    } } private static SearchRequest GetRequestProxy(out
    BingPortTypeClient client) { //When we added the service reference. Visual Studio automatically //added configuration information to app.config. //However since this assembly may be called from a number of processes //app.config won’t be available. As a result we need to manually //configure the service. Binding b = new BasicHttpBinding(); EndpointAddress address = new
    EndpointAddress(...); client = new BingPortTypeClient(b, address); SearchRequest request = new Microsoft.Bing.SearchRequest(); request.AppId = "ENTER YOUR APPID HERE"; //We’re only interested in search the Web source //See Bing SDK for more details on this parameter request.Sources = new SourceType[] { SourceType.Web }; return request;
    } }
  4. With the methods fleshed out, we can now build and deploy the model to SharePoint to see the results of our actions. Choose Build | Deploy BingConnectivity. The project will be built, packaged, and automatically installed on the SharePoint server that we specified when creating the project.
  5. In SharePoint Designer, navigate to the External Content Types explorer. You can see that a new WebResult content type has been added with type .Net Assembly. By opening the content type, you can see whether the metadata configuration is as expected and the appropriate operations have been added.

TIP The SharePoint server that’s used as the target for deployments can be changed by clicking the Project node in Solution Explorer and changing the Site URL property in the Properties pane.

Create a Custom Entity Object
One of the things you may notice when reviewing the properties of the WebResult External Content Type in SharePoint Designer is that no fields are defined. Of course, there is a perfectly reasonable explanation for this. If you look back at the return types for the ReadLst and ReadItem methods, you’ll see that they return values of type IEnumerable<string> and string, respectively. While this is a valid configuration, SharePoint Designer can’t break down a single string into multiple fields; therefore, no fields are shown.

This is where the Entity object comes into play. An Entity object, as you’ll remember, defines an individual row of data; it stores individual field data as properties. To show individual fields in SharePoint, we need to create an appropriate object.

Earlier in the chapter, we added a service reference to allow us to communicate with the Bing service. By examining the details of the service contract, we can determine what fields are returned from the service. From the Bing Web Service definition Language (WSDL), we see that the Search method returns an array of WebResult elements:

<xsd:complexType name="WebResult"><xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="1" name="Title" type="xsd:string" />
<xsd:element minOccurs="0" maxOccurs="1" name="Description" type="xsd:string" />
<xsd:element minOccurs="0" maxOccurs="1" name="Url" type="xsd:string" />
<xsd:element minOccurs="0" maxOccurs="1" name="CacheUrl" type="xsd:string" />
<xsd:element minOccurs="0" maxOccurs="1" name="DisplayUrl" type="xsd:string" />
<xsd:element minOccurs="0" maxOccurs="1" name="DateTime" type="xsd:string" />
<xsd:element minOccurs="0" maxOccurs="1" name="SearchTags" type="tns:ArrayOfWebSearchTag" />
<xsd:element minOccurs="0" maxOccurs="1" name="DeepLinks" type="tns:ArrayOfDeepLink" />

By creating an object with a property for each of these elements, we’ll be able to pass the results back to our client application without any loss of data. However, rather than create a new entity class from scratch, we can simply hook up our metadata to the object that was created automatically when we added the service reference. This eliminates the unnecessary step of reading the data from the proxy class into a custom entity class before passing it back to the client.

TIP Although we could jump straight in and change the return types of our ReadList and ReadItem methods, it’s always a good idea to make changes to the metadata first, since these changes areautomatically cascaded to the Entity Service. Following this procedure helps to eliminate mismatches in data types since the assembly won’t build if a type copied from the metadata model into the Entity Service code isn’t valid.

  1. Open the BdcModel1.bdcm model to display the Entity viewer. Since we want to change the data type for the return parameter of the ReadItem and ReadList methods, start by expanding the ReadItem method in the BDC Explorer pane.
  2. Select the WebResult Type Descriptor, and then in the Properties pane, change the Type Name.

  3. Repeat this process for the ReadList method, except change the Type Name for the WebResultList Type Descriptor to System. Collections. Generic. IEnumerable`1[[Bing Connectivity. Microsoft. Bing. WebResult, BdcModel1]] and the Type Name for Type Descriptor WebResult to BingConnectivity. Microsoft. Bing. WebResult, BdcModel1.
  4. Save the changes to the model, and then return to the WebResultService class. You’ll notice that the method signatures have been updated accordingly.
  5. As a result of these updates, our project no longer builds, because our code returns items of the wrong type. To fix this, update the ReadList method as follows:
  6. public static IEnumerable<WebResult> ReadList(string query) { //We can’t perform a web search with no query if (!string.IsNullOrEmpty(query)) { //Get an instance of the Bing proxy class BingPortTypeClient client; SearchRequest request = GetRequestProxy(out client); //Setup the request parameters request.Query = query; try { //Execute the search SearchResponse response = client.Search(request); return response.Web.Results; } catch(System.Exception) { return null;
    } else { return null; } }
  7. To resolve the errors in the ReadItem method, update the code as follows:
  8. public static WebResult ReadItem(string itemUrl) { if (!string.IsNullOrEmpty(itemUrl)) { BingPortTypeClient client; SearchRequest request = GetRequestProxy(out client); request.Query = itemUrl; SearchResponse response = client.Search(request); //Since urls are globally unique this query will only return one result return response.Web.Results.Single(); } else { return null; } }

    Our project will now build correctly.

Define Entity Metadata Before we redeploy our assembly, we need to make another important change. Even though we’ve updated the metadata to use the WebResult object as our Entity class, we haven’t added metadata defining the properties of the WebResult object. We need to update the WebResult Type Descriptor with details of the fields on the object that we want to allow clients to use.

  1. Open up the model. In the BDC Explorer pane, navigate to the WebResult Type Descriptor defined on the ReadItem method. Right-click the Type Descriptor node and select Add Type Descriptor. This will add a child-type descriptor object that we can use to declare details of a field.
  2. Add the following type descriptors:
  3. Define Entity Metadata

  4. In the properties for the Url type descriptor, set the Identifier to itemUrl to declare this as the identifier for the entity.
  5. Now that we’ve updated the WebResult type descriptor for the ReadItem method, we need to copy this information to the ReadList method. Thankfully the BDC Explorer tool allows us to copy and paste descriptors. Delete the existing WebResult descriptor from the ReadList method, and then copy the WebResult descriptor node on the ReadItem method.
  6. Navigate to the WebResultList node on the ReadList method. Click to highlight it, and then paste the WebResult node
  7. Define Entity Metadata

  8. we’re now good to redeploy our completed connectivity assembly. Choose Build | Deploy BingConnectivity.

Once the solution has been deployed, we can see in SharePoint Designer that the fields are now available as expected. (You might need to press F5 to refresh the view to see the changes.) We can test our model by creating an External List from it. Follow the procedure discussed in the section “Create an External List.”

When navigating to your new list for the first time, you’ll notice that it’s empty. This is expected, because the ReadList method requires a query property. So how do you set the property? In External Lists, data source filters can be defined as part of the view. If you modify the default ReadList view, you’ll find a Data Source Filters section containing a text box to enter a parameter for our Search Filter. Type a search query in the Search Filter text box and save the view to see the results displayed in the list:

Define Entity Metadata

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd Protection Status

Share Point 2010 Topics