Monday, September 27, 2010

AppComm Contest

Stone Bond Technologies is holding an AppComm (Application Communicators) contest for developers to take Enterprise Enabler® open source code and build AppComms to enable connectivity between disparate applications.
















Fore more details, visit http://www.enterpriseenabler.com/DeveloperZone/AppCommContest/tabid/427/Default.aspx

Friday, September 10, 2010

SharePoint Connectivity using Enterprise Enabler

Enterprise Enabler allows users to read and write data to and from multiple data sources using SharePoint BCS (Business Connectivity Services).

Enterprise Enabler uses application definition tool to create schema that will be useful to connect to external data sources.

Generating EE Application Definition.

EE Application definition Tool is used to create application definition for SharePoint 2010, SharePoint 2007 and wss.

Prerequisites

1. Source template or map.

2. Source Template or Destination Template should have only one block (Data will be shown only from one block).

3. Destination template block name will be used as the entity name in application definition.

4. Created objects should be deployed to the server. (Go to deployment manager and deploy the objects)

Steps to Create Application Definition.

1. Log in to Enterprise Enabler Studio.
clip_image002
2. Create templates and maps as required.
clip_image004
3. Deploy these objects to server by Clicking Deployment Manager menu button under Server menu.
clip_image006
clip_image008
4. Go to File -> New -> EE App Def (It will open following window)
clip_image010
clip_image012


5. Give a valid name for application definition. (This will be used in the connection string as Initial Catalog)

6. Click on Add Entity to create Entity.

a. If the map is already created, you can select that map to add entity.

b. If source template is available, you can create map automatically.

c. If CRUD operations are needed, you can auto generate update maps by checking the Auto Generate Edit Maps option.

d. Entity name will be selected from the destination template block name.
clip_image014
clip_image016
7. Once everything is ready, click on Generate Xml button to generated Business Data Catalog Xml file for 2007 or 2010.
clip_image018
clip_image020
8. For SharePoint 2010, definition can be automatically deployed to server if the logged in user has administrative privileges. For auto deployment, click on Deploy button in SharePoint 2010 section. It will show the following screen.
clip_image022
9. If user has administrative privileges, it will ask for the SharePoint admin site url to which the definition should be deployed.
clip_image024
10. Give the name of the Admin site url and click on ok button to complete the auto deployment.

Business Connectivity Services architecture

Business Connectivity Services architecture

A: The Business Data Connectivity service (BDC service) provides a means for storing and securing external content types and related objects. An external content type defines the following:

  • A named set of fields of data, such as "customer."
  • The operations for interacting with the data's external system, such as read, write, and create.
  • The connectivity information that lets solutions that use the external content type connect to the external system.

B: External content types are stored in a dedicated Business Data Connectivity service database.

C: The Secure Store Service securely stores credential sets for external systems and associates those credential sets with identities of individuals or with group identities. A common scenario for the Secure Store Service is a solution that authenticates against an external system in which the current user has a different account for authentication on that external system. When used with Business Data Connectivity service, the Secure Store Service provides a way to authenticate users and groups on external data sources.

D: Credential sets that the Secure Store Service uses are stored in a dedicated, secure database.

E: The Business Data Connectivity Server Runtime on front-end SharePoint servers uses the Business Data Connectivity data to connect to external systems and execute operations on the external systems for access by thin clients such as Web browsers.

F: The BCS Package Store holds the deployable Microsoft Business Connectivity Services packages that contain information that Microsoft Business Connectivity Services and Office applications need to interact with the external systems from rich clients.

G: The Business Data Connectivity service supports connecting to relational databases, Web services, Windows Communication Foundation (WCF) services, .NET connectivity assemblies, and custom data connectors that comply with the requirements of Microsoft Business Connectivity Services.

H: SharePoint Web sites use Business Data Web parts and SharePoint external lists to interact with external data that Microsoft Business Connectivity Services expose.

I: When users connect to an external list, a BCS package is downloaded to the client computers.

J: On supported Office clients (Microsoft SharePoint Workspace, Microsoft Outlook, and Microsoft Word), the Office Integration Client Runtime acts as a connector between Microsoft Business Connectivity Services running on the client and Office applications.

K: The Business Data Connectivity Client Runtime, on client computers, uses the Business Data Connectivity service data and Secure Store Service data to connect to and execute operations on external systems for access by supported rich clients.

L: Business Data Connectivity service data and Secure Store Service data is cached on client computers.

M: The Business Data Connectivity Runtime, on client computers, supports connecting to SQL Server and other relational databases, Web services, and custom data connectors that comply with the requirements of the Microsoft Business Connectivity Services.

N: The client cache refresh synchronizes the cache with the Microsoft Business Connectivity Services data and Secure Store Service data.

O: The Client Secure Store enables end users to configure their client mappings in the credential database.

P: Solution developers can use Microsoft SharePoint Designer 2010 and Visual Studio 2010 to create external content types and BDC models.

Sharepoint 2010 development using bcs

Nice blog on msdn By Steve Fox
One of the big features for SharePoint 2010 (and for building OBAs) is the Business Connectivity Services (BCS). I’ve written a few posts on this, but wanted to follow up on these early posts with some additional detail on how to create a solution leveraging web services. I see many customers trying to tie together SharePoint with external systems using a service-oriented design.

In this post, I’ll walk through how you can leverage a web service using the BCS (specifically employing the BDC Model project template in VS 2010) to create a read-only relationship with an external data source. This will be the first post in a series that will eventually cover the broad CRUD spectrum. So, let’s get down to it.

The high-level process you will want to go through is as follows:

  1. Create the data source;
  2. Create a service that interacts with your data source;
  3. Create the external content type using VS 2010; and
  4. Use the external content type in SP 2010 to create a web-service enabled external list.

Creating the Data Source

In this example, the data source is a SQL Server db with a single table with five records—see figure below. The number of records are less important than the structure of the columns.

image

You can choose to use something similar or create something different. If you use the code in this blog-post and you’re new to this, then create a db table with a similar structure. The following shows the data types in this simple table.

image

You create the new data source in SQL Server 2008 by right-clicking the Databases node and selecting New Database. Design your columns as per the above and then save the db when complete.

Creating the Web Service

With your db created, you now want to create a web service to interact with that db. We’ll create an ASP.NET service in this example to again keep things simple. (Note that you could equally apply much of the code to a WCF service.)

Open Visual Studio 2010 and create a new ASP.NET service application. You’ll want to add a new data source as an entity model. You can do this by click Data and then Add Data Source and then walking through the new data source wizard. I called my new data model CustomerSale—see the figure below to understand how Visual Studio interprets the data types.

image

You’ll need an in-memory object, so right-click your project and click Add and then select Class. Call your class CustomerSalesInfo.cs (or <name>.vb) and then click OK. You want to map the properties of your object to that of the data source. Here is the code for that object. You’ll note that I didn’t map the data types exactly. I do some in-code translation of data types.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace CustomerServiceBCSApp
{
    public class CustomerSalesInfo
    {
        public string custID { get; set; }
        public string custName { get; set; }
        public string custEmail { get; set; }
        public string custRegion { get; set; }
        public string custFY08Sales { get; set; }
        public string custFY09Sales { get; set; }
    }
}

Now you can write some code in your core service class. As this blog post is about read only, it will cover two web methods: one for reading the entire list and another for reading one item in a list. You’ll note that you require these two methods to create an external content type using BCS. In the code below, note that I’m creating a data context for my entity model called myCustomerData and there’s a class-level list collection I’m also creating called myCustomerList. The list collection is what I use to build out and populate my in-memory object (which I’ll return in the getAllCustomers() method. In fact, in the getAllCustomers() method I simply use a LINQ statement to query and get all of the data in the data context, and then I iterate through the members of the var returnListOfData object to creater my in-memory object. You may choose another method here (maybe even foregoing the in-memory object) to optimize your code. I pass no parameters to the getAllCustomers method as this is my, so to speak, “SELECT *” statement.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace CustomerServiceBCSApp
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class Service1 : System.Web.Services.WebService
    {
        CustomersEntities myCustomerData = new CustomersEntities();
        List<CustomerSalesInfo> myCustomerList = new List<CustomerSalesInfo>();

        [WebMethod]
        public List<CustomerSalesInfo> getAllCustomers()
        {
                var returnListOfData = (from customer in myCustomerData.CustomerSales
                                  select customer).ToArray();

                foreach (var cust in returnListOfData)
                {
                    CustomerSalesInfo tempCustomer = new CustomerSalesInfo();
                    tempCustomer.custID = cust.CustomerID.ToString();
                    tempCustomer.custName = cust.CustomerName.ToString();
                    tempCustomer.custEmail = cust.CustomerEmail.ToString();
                    tempCustomer.custRegion = cust.CustomerRegion.ToString();
                    tempCustomer.custFY08Sales = cust.CustomerFY08Sales.ToString();
                    tempCustomer.custFY09Sales = cust.CustomerFY09Sales.ToString();
                    myCustomerList.Add(tempCustomer);
                };

             return myCustomerList;
        }

        [WebMethod]
        public string[] getACustomer(string strparamCustomerID)
        {
            int tempIntCustomerIDParam = Int32.Parse(strparamCustomerID);
            string[] myCustomerList = new string[6];

            var returnIndiviualDataItem = (from customer in myCustomerData.CustomerSales
                                .Where(x => x.CustomerID == tempIntCustomerIDParam)
                                           select customer);

            foreach (var cust in returnIndiviualDataItem)
            {
                myCustomerList[0] = cust.CustomerID.ToString();
                myCustomerList[1] = cust.CustomerName.ToString();
                myCustomerList[2] = cust.CustomerEmail.ToString();
                myCustomerList[3] = cust.CustomerRegion.ToString();
                myCustomerList[4] = cust.CustomerFY08Sales.ToString();
                myCustomerList[5] = cust.CustomerFY09Sales.ToString();
            }

            return myCustomerList;
        }   

    }
}

The second method takes a string parameter (a customer ID) and then builds a LINQ query based on that parameter. In this instance, I wanted to use a string array that I can easily parse on the other side. I do prefer to leverage generics wherever possible because I like the flexibility of dynamic collections as opposed to hard-coded lengths, but for this sample I though it interesting enough to show both examples.

Once you’ve gotten this far, you can test out the web service to make sure it runs. Test it from VS 2010 and then deploy it to IIS. To do this, create a new folder in your wwwroot folder (I called mine SPConnections) and then publish your service to that directory.

image

To publish the service, right-click your web service project select Publish and complete the options in the Publish Web dialog. Specifically, change the Publish Method to File System and then point the Target Location to the folder you just created under wwwroot.

image

Click Publish to publish the service to that directory. Now, any time you make changes you can simply click Publish and your service definition and code will be updated.

Since you’ve published your service to the file system, you’ll now want to create a web application in IIS that points to this service. To do this, open IIS and right-click the Sites node and select Add Web Site. Provide a name for the site, map the physical path to the folder under wwwroot (where you published your service to), give the site a unique port (e.g. 1111), click the Connect As button to provide the appropriate permissions for the service. (Note that you may have issues accessing the SQL Server if you have not configured the App Pool correctly—e.g. you can access using Local System or Network Service as opposed to the native Application Pool Identity.) Enable Windows Forms authentication by clicking Authentication and then clicking Windows and then Enable.

To test the service from IIS, click the Content tab and then right-click Service1.asmx and select Browse. You should be able to execute both methods—one to get all of the customers in your db and the other (by passing a customer ID that exists within your db) to get a specific customer.

Creating the External Content Type (ECT)

You’ll create the ECT using the new BDC Model project. To find this, click File, New, Project, and then in the SharePoint 2010 folder select Business Data Connectivity Model. Provide a name for your project and click OK.   image

Using this template is a little different from SharePoint Designer (SPD) 2010, which also enables you to build out ECTs. My personal feeling is that SPD is a little easier to create the ECTs, but then if you want to have more complex projects that perhaps leverage other parts of the .NET Framework then using the VS project is better. Note that VS also deploys the ECT (and all associated code) as a feature as opposed to an XML file to the Metadata Store (as is the case with SPD 2010).

Okay, now you have your project set up you need to edit the Entity1 object to map to your external data source entity. You’ll note that I’ve kept a lot of the default namespaces and objects in this example. I’ll change these in future posts and keep you apprised as to the places you’ll need to look out for when trying to update/change these. To follow is what your Entity1 should now look like.

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

namespace WroxTestBDC.BdcModel1
{
        public partial class Entity1
    {
        public string Identifier1 { get; set; }
        public string custName { get; set; }
        public string custEmail { get; set; }
        public string custRegion { get; set; }
        public string custFY08Sales { get; set; }
        public string custFY09Sales { get; set; }
    }
}

As a general rule of thumb, as soon as you’ve made the change to your Entity1 object go immediately to your .bdcm (the ECT model) and amend the entity structure there as well, or your deploy will fail. Also note that the way in which you edit your methods should actually correspond to the code-behind. For example, the structure of my ReadItem method (which is where I’ll call my getACustomer web method) passes the Identifier1 parameter and returns an object from my database via the web method. Similarly, the ReadList method will return a list of objects, and it defines this return object through the Entity1List object in the taxonomy below.

image

Now, note again I’m only doing a read-only transaction—mostly because this is a good jumping off point but also because these two methods are created by default for you.

Okay, before we jump to the code behind add a reference to the web service. To do this, right-click the BCS project and select Add Service Reference. Add the URL to the service (copy and paste the URL from your IIS browse) in the Service field, provide a name for your service and click OK.

At this point, you are now ready to implement the service (i.e. the two web methods you created) in the VS project.

Navigate to the Entity1Service.cs file and make sure your code looks like the following code snippet. You can see that I create an instance of the service and then call the appropriate method on that service to return the code from my external data source. Note that in the case of the ReadItem method, it takes a string parameter (which would get activated when you click on a record in the external list). I’ve changed the default IEnumerable return object to use my preferred List<> object (which is essentially a list collection of the Entity1 object).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WroxTestBDC.CustomerSalesWS;
using System.Xml.Serialization;
using System.Xml;
using System.Xml.Linq;

namespace WroxTestBDC.BdcModel1
{
    public class Entity1Service
    {
        public static Entity1 ReadItem(string id)
        {
            CustomerSalesWS.Service1SoapClient myWSProxy = new CustomerSalesWS.Service1SoapClient();
            string[] returnedData = new string[6];
            returnedData = myWSProxy.getACustomer(id).ToArray();

            Entity1 entity1 = new Entity1();

            entity1.Identifier1 = id;
            entity1.custName = returnedData[1];
            entity1.custEmail = returnedData[2];
            entity1.custRegion = returnedData[3];
            entity1.custFY08Sales = returnedData[4];
            entity1.custFY09Sales = returnedData[5];

            return entity1;
        }

        public static List<Entity1> ReadList()
        {
            CustomerSalesWS.Service1SoapClient myWSProxy = new CustomerSalesWS.Service1SoapClient();
            var salesData = myWSProxy.getAllCustomers();

            List<Entity1> mySalesInfoList = new List<Entity1>();

            foreach (var item in salesData)
            {
                Entity1 tempEntity = new Entity1();
                tempEntity.Identifier1 = item.custID.ToString();
                tempEntity.custName = item.custName.ToString();
                tempEntity.custEmail = item.custEmail.ToString();
                tempEntity.custRegion = item.custRegion.ToString();
                tempEntity.custFY08Sales = item.custFY08Sales.ToString();
                tempEntity.custFY09Sales = item.custFY09Sales.ToString();
                mySalesInfoList.Add(tempEntity);
            }

            return mySalesInfoList;
        }

     }
}

At this point, you can build and deploy the ECT by right-clicking the project and selecting Deploy.

Before you go to SharePoint, one thing you’ll need to make sure you do is to copy the property settings for your system.serviceModel in your app.config file to your SharePoint’s web.config file—else you will get nasty web configuration errors.

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="Service1Soap" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:289/Service1.asmx" binding="basicHttpBinding"
                bindingConfiguration="Service1Soap" contract="CustomerSalesWS.Service1Soap"
                name="Service1Soap" />
        </client>
    </system.serviceModel>

After this, you are now ready to create the external list in SharePoint 2010 using your newly create web-service enabled ECT.

Creating the External List

You can now create the external list in SharePoint. To do this, click the All Site Content link and click Create. Then in the Create options, click List and click External List. Click Create.

image

When the External List page opens, provide a name for the list and then in the External Content Type field click the right-most icon to browse for external content types that have been deployed to SharePoint. Click Create when complete.

image

At this point, your external list will have been created. The two read operations will enable you to have the full list of your records in the Customers database (via web service) rendered in the list—see below.

image

And if you click on one of the records it will display the individual record—see below.

image

And there you have it. You now have a web-service enabled external list.

In future posts, I will show you how to add new web methods to handle update, create and delete and then add the corresponding code in the BDC project you just created.

Debugging the .NET framework source code

Nice article on MSDN Blogs
Debugging the .NET framework source code by  mcsuksoldev

I am sure lots of us have been in the situation where, after hours of poring through compiled source code in Reflector whilst simultaneously trying to hold the values of hundreds of conspiratorial variables in our heads, we are left thinking that it would all be so much easier if we could just set a breakpoint in the compiled code and step into it. In this way all of the power of Visual Studio debugging tools would be available to us, making the diagnostic process a more familiar and user-friendly experience.

All is not lost. The Shared Source Initiative, and specifically the Reference Source Code Center, gives developers the ability to step into .NET framework source code. Actually this ability has been around for a while but seems to receive relatively little press. It therefore seems worth writing a post so as to get a little more momentum going around the subject.

By the way, this is described in the Visual Studio literature and yet I always seem to have trouble finding it. That probably says more about my inability to use IE bookmarks but hey, none of us is perfect!

Ok, create a Visual Studio 2010 console application and overwrite Program.cs with the following:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

class Program{
static void Main(string[] args)
{
XmlReader r = XmlReader.Create(”http://helloworld”);
}
}



Go to Project-Properties-Debug and do the following:




  1. Uncheck the ‘Enable the Visual Studio hosting process’ checkbox


  2. Save the project



image_4_5DE2FE80



Now go to Tools-Options-Debugging-General and do the following:




  1. Uncheck ‘Enable Just My Code (Managed only)’


  2. Check ‘Enable .NET Framework source stepping’


  3. Check ‘Require source files to exactly match the original version’



image_7_5DE2FE80



Now go to Tools-Options-Debugging-Symbols and do the following:




  1. Check ‘Microsoft Symbol Servers’


  2. Choose a suitable directory to store the symbols


  3. Choose either to load all symbols or specified modules

    • The former is the safest approach but also the bigger performance hit




  4. Click ‘OK’



image_14_205ABBD5



Whilst the symbols are downloading from the reference server you will see something like the following:



image_18_4E480E8D



Finally, set a breakpoint on the line of code in the console app and press F5. Once the breakpoint has been hit, press F11 to step into the framework code, in this case System.Xml.dll (NB – you may have to agree to a EULA the first time you try this).



You will see something like the following:



image_22_4E480E8D



You are now able to debug framework code in the same way as your own custom code.



NB - You may experience problems with the odd variable here and here and this is most likely due to the issue described in the FAQ section of the reference source website. Additionally, there is a great MSDN forum where relevant topics are discussed. Also, not all of the source code symbols are available. You can see what is available here.



Finally I would recommend switching off this functionality when it is not needed as it is a significant performance overhead in Visual Studio.



Written by Bradley Cotier