pgup12 发表于 2015-9-25 09:22:25

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;

public interface IAdventureWorks2000WCFService
{

      
      List<Contact> GetContactFinder();
   
      
      Contact GetContactSpecificFinder(Int32 contactid);
   
      
      List<Int32> GetContactIdEnumerator();
   
}

public class Contact
{

      
      public Int32 ContactID
      {
      get;
      set;
      }
   
      
      public String Salutation
      {
      get;
      set;
      }
   
      
      public String FirstName
      {
      get;
      set;
      }
   
      
      public String MiddleName
      {
      get;
      set;
      }
   
      
      public String LastName
      {
      get;
      set;
      }
   
      
      public Boolean NameStyle
      {
      get;
      set;
      }
   
      
      public String Phone
      {
      get;
      set;
      }
   
      
      public String Suffix
      {
      get;
      set;
      }
   
      
      public String EmailAddress
      {
      get;
      set;
      }
   
      
      public String Password
      {
      get;
      set;
      }
   
      
      public Int32 EmailPromotion
      {
      get;
      set;
      }
   
      
      public DateTime ModifiedDate
      {
      get;
      set;
      }
   
      
      public Guid rowguid
      {
      get;
      set;
      }
   
      
      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. ";
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.");
foreach (DataRow dr in dataSet.Tables.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. 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.");
if(dataSet.Tables.Rows.Count > 0)
{
DataRow dr = dataSet.Tables.Rows;
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.";
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.");
foreach (DataRow dr in dataSet.Tables.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 inSharePoint 2010
BCS PowerShell: Introduction and ThrottleManagement
页: [1]
查看完整版本: SharePoint Designer 2010中的外部内容类型-WCF