SharePoint Designer 2010中的外部内容类型-WCF

本文将带领大家使用SharePoint Designer创建基于WCF服务的外部内容类型。

步骤

1、检查你的WCF服务已经宿主并可用。本文将使用封装AdventureWorks2000数据库的Contact表得到的WCF服务。 首先打开你的IIS管理器,导航到宿主你的WCF服务的网站,确保其正常运行。

 

 

2、打开IE浏览器并导航到该服务的.svc文件。 你应该能够看到类型如下的页面,表示该WCF服务正在工作。

 


WCF的检查工作结束。现在我们开始基于该WCF在SPD中创建我们的外部内容类型。

3、打开SharePoint Designer 2010并点击“打开网站”大按钮。


[点击图片可查看完整尺寸]

4、输入你的SharePoint站点URL地址并回车。SPD将会连接到该站点并获取信息。


[点击图片可查看完整尺寸]

5、从左侧导航窗格中点击外部内容类型。可以看到顶部的功能区也进行了相应的改变,反映当前的工作状态。

6、在功能区中,点击新建中的外部内容类型。

7、打开的摘要页面中,可以编辑和管理外部内容类型。


[点击图片可查看完整尺寸]

这里有一些类似超链接的标签,点击可设置值 。最上面的两个是名称和显示名称,设置其值为:

 

名称:联系人

显示名称:联系人 

 

接下来,我们选择一个外部数据源来进行连接。点击链接“点击此处发现数据源并定义操作”。

8、进入操作设计器视图。点击添加连接按钮。


[点击图片可查看完整尺寸]

9、选择数据源类型为 “WCF服务”

 

10、WCF连接窗口打开。这里我们需要填写有关我们WCF服务的一些连接信息,以便SharePoint Designer进行连接。根据上面我们检查到的WCF宿主情况,这里我填入:

服务元数据URL:http://contact/service.svc?WSDL

服务终结点URL:http://contact/service.svc 

 

11、配置好WCF连接后,点击确定。这时将尝试连接到你的WCF服务。如果一切正常,你会看到所有可用的Web方法。

 

12、我们需要创建相应的BCS操作。本例中,我们将使用GetContactFinder作为“读取列表”操作,使用GetContactSpecificFinder作为“读取项”操作。

13、右击 GetContactFinder并选择“新建读取列表”操作。

 

14、在弹出的向导中,“返回参数” 一节中会提示一个错误信息,“应至少指定一个标识符”。选择ContactID并勾选“映射到标识符”。在标识符下拉框中选中ContactID。点击完成,创建好了读取列表操作。

 

15、右击GetContactSpecificFinder并选择新建“读取项”操作。

 

16、在操作属性窗口中,输入参数一节我们需要映射该输入参数到标识符。选中contactid并在右侧的面板中勾上“映射到标识符”,并在标识符下拉框中选中ContactID。点击下一步。

 

 

17、在返回参数一节,也包含一条错误提示指出需要映射标识符。为了修复该错误,在左侧选择ContactID,右侧勾选“映射到标识符” 并在标识符下拉框中选中ContactID。点击完成按钮。 

 

18、现在,右侧的ECT操作中已经有两个操作了。你也可以根据需要添加其他操作,如创建,更新等等。

 

19、按“Ctrl+S”键保存该ECT。 

 

20、我们可以打开SharePoint站点,创建外部列表绑到我们的外部内容类型。 

 

21、它会调用“读取列表”操作 (WCF中的Finder方法)来获取数据。


22、选中任意一条数据,然后点击“项目”功能区,其中的“查看项目”操作会调用WCF的Specific Finder方法,在弹出框中显示选中的项。 

 

 

附上本例中涉及的WCF相关代码,以备参考。

1、IAdventureWorks2000WCFService.cs

代码
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;

[ServiceContract]
public interface IAdventureWorks2000WCFService
{
  
      [OperationContract]
      List
<Contact> GetContactFinder();
    
      [OperationContract]
      Contact GetContactSpecificFinder(Int32 contactid);
    
      [OperationContract]
      List
<Int32> GetContactIdEnumerator();
    
}

[DataContract]
public class Contact
{
  
      [DataMember]
      
public Int32 ContactID
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public String Salutation
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public String FirstName
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public String MiddleName
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public String LastName
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public Boolean NameStyle
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public String Phone
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public String Suffix
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public String EmailAddress
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public String Password
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public Int32 EmailPromotion
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public DateTime ModifiedDate
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public Guid rowguid
      {
      
get;
      
set;
      }

    
      [DataMember]
      
public String AdditionalContactInfo
      {
      
get;
      
set;
      }

    
}

 

2、 AdventureWorks2000WCFService.cs

代码
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
public class AdventureWorks2000WCFService : IAdventureWorks2000WCFService
{
  
private const string connectionString = @"Persist Security Info=False;User ID=xxx;Password=xxx;Server=localhost;Connect Timeout=30;Initial Catalog=AdventureWorks2000";
  


  
  AdventureWorks2000WCFService()
  {    
  }

  
  
public List<Contact> GetContactFinder()
  {
  List
<Contact> contactList = new List<Contact>();

  
const string sqlQuery = @"Select * From dbo.[Contact] ";

  
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
  {
  sqlConnection.Open();

  SqlCommand comm 
= new SqlCommand(sqlQuery, sqlConnection);
  
  DataSet dataSet 
= new DataSet();

  SqlDataAdapter adapter 
= new SqlDataAdapter(comm);
  adapter.Fill(dataSet, 
@"dbo.[Contact]");

  
foreach (DataRow dr in dataSet.Tables[0].Rows)
  {
  Contact contact 
= new Contact();

  contact.ContactID 
= dr["ContactID"is DBNull ? 0 : (Int32)dr["ContactID"];
contact.Salutation 
= dr["Salutation"is DBNull ? string.Empty : (String)dr["Salutation"];
contact.FirstName 
= dr["FirstName"is DBNull ? string.Empty : (String)dr["FirstName"];
contact.MiddleName 
= dr["MiddleName"is DBNull ? string.Empty : (String)dr["MiddleName"];
contact.LastName 
= dr["LastName"is DBNull ? string.Empty : (String)dr["LastName"];
contact.NameStyle 
= dr["NameStyle"is DBNull ? false : (Boolean)dr["NameStyle"];
contact.Phone 
= dr["Phone"is DBNull ? string.Empty : (String)dr["Phone"];
contact.Suffix 
= dr["Suffix"is DBNull ? string.Empty : (String)dr["Suffix"];
contact.EmailAddress 
= dr["EmailAddress"is DBNull ? string.Empty : (String)dr["EmailAddress"];
contact.Password 
= dr["Password"is DBNull ? string.Empty : (String)dr["Password"];
contact.EmailPromotion 
= dr["EmailPromotion"is DBNull ? 0 : (Int32)dr["EmailPromotion"];
contact.ModifiedDate 
= dr["ModifiedDate"is DBNull ? DateTime.MinValue : (DateTime)dr["ModifiedDate"];
contact.rowguid 
= dr["rowguid"is DBNull ? Guid.Empty : (Guid)dr["rowguid"];
contact.AdditionalContactInfo 
= dr["AdditionalContactInfo"is DBNull ? string.Empty : (String)dr["AdditionalContactInfo"];


  contactList.Add(contact);
  }
  }


  
return contactList;
  }
public Contact GetContactSpecificFinder(Int32 contactid)
  {
  Contact contact 
= new Contact();

  
const string sqlQuery = @"Select * From dbo.[Contact] Where (ContactID=@ContactID)";

  
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
  {
  sqlConnection.Open();

  SqlCommand comm 
= new SqlCommand(sqlQuery, sqlConnection);
  comm.Parameters.AddWithValue(
"@ContactID", contactid);
  DataSet dataSet 
= new DataSet();

  SqlDataAdapter adapter 
= new SqlDataAdapter(comm);
  adapter.Fill(dataSet, 
@"dbo.[Contact]");

  
if(dataSet.Tables[0].Rows.Count > 0)
  {
  DataRow dr 
= dataSet.Tables[0].Rows[0];
  contact.ContactID 
= dr["ContactID"is DBNull ? 0 : (Int32)dr["ContactID"];
contact.Salutation 
= dr["Salutation"is DBNull ? string.Empty : (String)dr["Salutation"];
contact.FirstName 
= dr["FirstName"is DBNull ? string.Empty : (String)dr["FirstName"];
contact.MiddleName 
= dr["MiddleName"is DBNull ? string.Empty : (String)dr["MiddleName"];
contact.LastName 
= dr["LastName"is DBNull ? string.Empty : (String)dr["LastName"];
contact.NameStyle 
= dr["NameStyle"is DBNull ? false : (Boolean)dr["NameStyle"];
contact.Phone 
= dr["Phone"is DBNull ? string.Empty : (String)dr["Phone"];
contact.Suffix 
= dr["Suffix"is DBNull ? string.Empty : (String)dr["Suffix"];
contact.EmailAddress 
= dr["EmailAddress"is DBNull ? string.Empty : (String)dr["EmailAddress"];
contact.Password 
= dr["Password"is DBNull ? string.Empty : (String)dr["Password"];
contact.EmailPromotion 
= dr["EmailPromotion"is DBNull ? 0 : (Int32)dr["EmailPromotion"];
contact.ModifiedDate 
= dr["ModifiedDate"is DBNull ? DateTime.MinValue : (DateTime)dr["ModifiedDate"];
contact.rowguid 
= dr["rowguid"is DBNull ? Guid.Empty : (Guid)dr["rowguid"];
contact.AdditionalContactInfo 
= dr["AdditionalContactInfo"is DBNull ? string.Empty : (String)dr["AdditionalContactInfo"];

  }
  }


  
return contact;
  }
public List<Int32> GetContactIdEnumerator()
  {
  List
<Int32> ids = new List<Int32>();

  
const string sqlQuery = @"Select ContactID from dbo.[Contact]";

  
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
  {
  sqlConnection.Open();

  SqlCommand comm 
= new SqlCommand(sqlQuery, sqlConnection);

  DataSet dataSet 
= new DataSet();

  SqlDataAdapter adapter 
= new SqlDataAdapter(comm);
  adapter.Fill(dataSet, 
@"dbo.[Contact]");

  
foreach (DataRow dr in dataSet.Tables[0].Rows)
  {
  ids.Add(dr[
"ContactID"is DBNull ? 0 : (Int32)dr["ContactID"]);
  }
  }


  
return ids;
  }


}

 

3、Service.svc

<%@ ServiceHost Language="C#" Debug="true" Service="AdventureWorks2000WCFService" CodeBehind="~/App_Code/AdventureWorks2000WCFService.cs" %>

 

4、Web.config

代码
<?xml version="1.0"?>
<!--
    Note: As an alternative to hand editing this file you can use the 
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in 
    machine.config.comments usually located in 
    \Windows\Microsoft.Net\Framework\v2.x\Config 
-->
<configuration>
    
<configSections>
        
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
            
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
                
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
                    
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
                    
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                    
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                    
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                
</sectionGroup>
            
</sectionGroup>
        
</sectionGroup>
    
</configSections>
    
<appSettings/>
    
<connectionStrings/>
    
<system.web>
        
<!--
            Set compilation debug="true" to insert debugging 
            symbols into the compiled page. Because this 
            affects performance, set this value to true only 
            during development.
        
-->
        
<compilation debug="true">
            
<assemblies>
                
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
                
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        
      
</assemblies>
        
</compilation>
        
<!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
        
-->
        
<authentication mode="Windows"/>
        
<!--
            The <customErrors> section enables configuration 
            of what to do if/when an unhandled error occurs 
            during the execution of a request. Specifically, 
            it enables developers to configure html error pages 
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        
-->
        
<pages>
            
<controls>
                
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            
</controls>
        
</pages>
        
<httpHandlers>
            
<remove verb="*" path="*.asmx"/>
            
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
        
</httpHandlers>
        
<httpModules>
            
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        
</httpModules>
    
</system.web>
    
<system.codedom>
        
<compilers>
            
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
                
<providerOption name="CompilerVersion" value="v3.5"/>
                
<providerOption name="WarnAsError" value="false"/>
            
</compiler>
            
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
                
<providerOption name="CompilerVersion" value="v3.5"/>
                
<providerOption name="OptionInfer" value="true"/>
                
<providerOption name="WarnAsError" value="false"/>
            
</compiler>
        
</compilers>
    
</system.codedom>
    
<system.web.extensions>
        
<scripting>
            
<webServices>
                
<!--
              Uncomment this section to enable the authentication service. Include 
              requireSSL="true" if appropriate. 

          <authenticationService enabled="true" requireSSL = "true|false"/>
          
-->
                
<!--
              Uncomment these lines to enable the profile service, and to choose the 
              profile properties that can be retrieved and modified in ASP.NET AJAX 
              applications.

           <profileService enabled="true"
                           readAccessProperties="propertyname1,propertyname2"
                           writeAccessProperties="propertyname1,propertyname2" />
          
-->
                
<!--
              Uncomment this section to enable the role service.

          <roleService enabled="true"/>
          
-->
            
</webServices>
            
<!--
        <scriptResourceHandler enableCompression="true" enableCaching="true" />
        
-->
        
</scripting>
    
</system.web.extensions>
    
<!--
        The system.webServer section is required for running ASP.NET AJAX under Internet
        Information Services 7.0.  It is not necessary for previous version of IIS.
    
-->
    
<system.webServer>
        
<validation validateIntegratedModeConfiguration="false"/>
        
<modules>
            
<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        
</modules>
        
<handlers>
            
<remove name="WebServiceHandlerFactory-Integrated"/>
            
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        
</handlers>
    
<directoryBrowse enabled="true" />
    
</system.webServer>
    
<system.serviceModel>
        
<services>
            
<service name="AdventureWorks2000WCFService" behaviorConfiguration="ServiceBehavior">
                
<!-- Service Endpoints -->
                
<endpoint address="" binding="basicHttpBinding" contract="IAdventureWorks2000WCFService">
                    
<!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          
-->
                    
<identity>
                        
<dns value="contact"/>
                    
</identity>
                
</endpoint>
                
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
            
</service>
        
</services>

    
<behaviors>
            
<serviceBehaviors>
                
<behavior name="ServiceBehavior">
          
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
                    
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
                    
<serviceMetadata httpGetEnabled="true"/>
                    
<!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                    
<serviceDebug includeExceptionDetailInFaults="false"/>
                
</behavior>
            
</serviceBehaviors>
        
</behaviors>
    
</system.serviceModel>
</configuration>

 

 

参考资料

spd external content type from wcf

Large List Throttling for External Lists in SharePoint 2010

BCS PowerShell: Introduction and Throttle Management
posted @ 2010-06-28 23:52  Sunmoonfire  阅读(1558)  评论(0编辑  收藏  举报