DataSet和DataTable类型是可序列化的,因而我们可以在服务契约中接收或返回数据表或数据集。
如果服务契约使用了DataSet和DataTable类型,生成的代理文件不会直接使用DataSet和DataTable类型,而是包含DataTable数据契约的定义(只包含DataTable的样式,而不包含任何代码)。但我们可以手工修改这些定义。例如这样的服务契约:
那么生成的代理文件可能会是这样:[ServiceContract()] public interface IContactManager { [OperationContract] void AddContact(Contact contact); [OperationContract] void AddContacts(DataTable contacts); [OperationContract] DataTable GetContacts(); }
public interface IContactManager { [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IContactManager/AddContact", ReplyAction="http://tempuri.org/IContactManager/AddContactResponse")] [System.ServiceModel.XmlSerializerFormatAttribute()] void AddContact(Contact contact); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IContactManager/AddContacts", ReplyAction="http://tempuri.org/IContactManager/AddContactsResponse")] [System.ServiceModel.XmlSerializerFormatAttribute()] AddContactsResponse AddContacts(AddContactsRequest request); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IContactManager/GetContacts", ReplyAction="http://tempuri.org/IContactManager/GetContactsResponse")] [System.ServiceModel.XmlSerializerFormatAttribute()] GetContactsResponse GetContacts(GetContactsRequest request); } 代理类的定义则如下所示: [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public partial class ContactManagerClient : System.ServiceModel.ClientBase<IContactManager>, IContactManager { //其余成员略; public void AddContact(Contact contact) { base.Channel.AddContact(contact); } AddContactsResponse IContactManager.AddContacts(AddContactsRequest request) { return base.Channel.AddContacts(request); } public void AddContacts(AddContactsContacts contacts) { AddContactsRequest inValue = new AddContactsRequest(); inValue.contacts = contacts; AddContactsResponse retVal = ((IContactManager)(this)).AddContacts(inValue); } GetContactsResponse IContactManager.GetContacts(GetContactsRequest request) { return base.Channel.GetContacts(request); } public GetContactsResponseGetContactsResult GetContacts() { GetContactsRequest inValue = new GetContactsRequest(); GetContactsResponse retVal = ((IContactManager)(this)).GetContacts(inValue); return retVal.GetContactsResult; } }
我们可以手动将AddContacts()与GetContacts()方法修改为:
public void AddContacts(DataTable contacts) { AddContactsRequest inValue = new AddContactsRequest(); inValue.contacts = contacts; AddContactsResponse retVal = ((IContactManager)(this)).AddContacts(inValue); } public DataTable GetContacts() { GetContactsRequest inValue = new GetContactsRequest(); GetContactsResponse retVal = ((IContactManager)(this)).GetContacts(inValue); return retVal.GetContactsResult; }
当然,前提条件是我们需要修改AddContactRequest类以及GetContactsResponse,例如将AddContactRequest类的contacts成员由原来的AddContactsContacts类型修改为DataTable类型;将GetContactsResponse中的GetContactsResult成员由原来的GetContactsResponseGetContactsResult类型修改为DataTable类型。
自动生成的代理类非常复杂,实际上我们完全可以简化。首先将客户端的服务契约定义修改为与服务端服务契约完全一致的定义:
[ServiceContract()] public interface IContactManager { [OperationContract] void AddContact(Contact contact); [OperationContract] void AddContacts(DataTable contacts); [OperationContract] DataTable GetContacts(); }
然后修改代理类ContactManagerClient:
public partial class ContactManagerClient : System.ServiceModel.ClientBase<IContactManager>, IContactManager { public void AddContact(Contact contact) { base.Channel.AddContact(contact); } public void AddContacts(DataTable contacts) { base.Channel.AddContacts(contacts); } public DataTable GetContacts() { return base.Channel.GetContacts(); } }