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.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.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
4、Web.config

<!--
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!