2011-03-29 52 views
0

我有一个使用web service software factory创建的WCF服务。我所有的传入请求和返回的响应都是作为消息合约实现的。我一直通过在VS中添加服务引用来访问该服务,该服务工作正常。不过,我现在被告知,这不是标准的公司方式,我需要使用基于System.ServiceModel.ChannelFactory的内部WCF代理辅助类来调用该服务。如何重写WCF客户端使用ChannelFactory而不是服务引用

我以前从未使用过ChannelFactory,我正在努力想出重写客户端访问的最佳方式。服务合约由服务工厂生成,我需要为代理助手类提供服务接口。这里的服务合同的一部分 - 有总共约25行动上的服务:

namespace CAEWCFService.ServiceContracts 
{ 
    /// <summary> 
    /// Service Contract Class - CAEServiceContract 
    /// </summary> 
    [WCF::ServiceContract(Namespace = "urn:CAEServiceServiceContracts", Name = "CAEServiceContract", SessionMode = WCF::SessionMode.Allowed, ProtectionLevel = ProtectionLevel.None)] 
    public partial interface ICAEServiceContract 
    { 
    [WCF::OperationContract(IsTerminating = false, IsInitiating = true, IsOneWay = false, AsyncPattern = false, Action = "GetAllIncomes", ProtectionLevel = ProtectionLevel.None)] 
    CAEService.MessageContracts.GetAllIncomesReponse GetIncomeRecords(CAEService.MessageContracts.GetAllIncomesRequest request); 

    [WCF::OperationContract(IsTerminating = false, IsInitiating = true, IsOneWay = false, AsyncPattern = false, Action = "urn:CAEServiceServiceContracts.CAEServiceContract.GetSecurityRecords", ProtectionLevel = ProtectionLevel.None)] 
    CAEService.MessageContracts.GetAllSecuritiesResponse GetSecurityRecords(CAEService.MessageContracts.GetAllSecuritiesRequest request); 

    //... the rest 
    } 
} 

下面是从客户端调用GetIncomeRecords操作呼叫:

CAEServiceContractClient client = new CAEServiceContractClient();  

IncomeSearchItem item = new IncomeSearchItem() 
{ 
    aCode = aCode.Text, 
    bCode = bCode.Text, 
    sCode = sCode.Text, 
    secDesc = tbSecurityName.Text, 
    status = statusValue != 0 ? statusValue : 0, 
    fromDate = fromDate, 
    toDate = toDate, 
    IncomeID = 0, 
    userBank = userBank, 
    userId = userId, 
    currentRate = currentSourceVal != 0 ? currentSourceVal : 0, 
    dateConfirmed = ddDate.SelectedValue, 
    pageIndex = pageIdx, 
    pageSize = recordsPerPage 
}; 

GetAllIncomesReponse response = new GetAllIncomesReponse(); 

try 
{ 
    response = client.GetIncomeRecords(item); 
    totalRecords = response.TotalRecords; 

    incomelist.DataSource = response.IncomeItemColl; 
    incomelist.DataBind(); 

    //.. the rest 
} 

下面是一些示例代码从另一个显示如何使用代理帮助程序的项目。我服务的问题是,它期望在基本类型返回的消息,而合同样本一个通行证,并返回原语或数据集:

public static class ServiceHelper 
{ 
    /// <summary> 
    /// Services the verification. 
    /// </summary> 
    /// <param name="user">The user.</param> 
    /// <returns></returns> 
    public static string ServiceVerification(string user) 
    { 
    return WCFProxyHelper<IFCAServices>.Use(client => 
     client.ServiceVerification(user)); 
    } 
} 

那么什么是做到这一点的最快/最简单的方法是什么?如何让ChannelFactory知道我的IncomeSearchItem和我需要传递给该服务的其他几个对象?可以/我应该使用svcutil生成所有对象并在ChannelFactory中使用它?

回答

1

你是说“公司之道”是使用服务助手,并且它在内部创建了一个基于ChannelFactory的代理 - 或者,你是否想要长时间创建自己的代理类。这对你有用吗? ServiceHelper上的扩展方法可让您保持使用公司的方式,但不会要求将ServiceHelper更改为了解您的请求/响应消息或其中包含的任何内容。

using CAEService; 
using CAEService.MessageContracts; 

public static class ServiceHelperExtensions 
{ 
    public static GetAllIncomesReponse GetIncomeRecords(this ServiceHelper, GetAllIncomesRequest request) 
    { 
     return WCFProxyHelper<ICAEServiceContract>.Use(client => 
      client.GetAllIncomes(request)); 
    } 
} 

然后在客户端的代码,你将取代这个:

response = client.GetIncomeRecords(item); 

与此:

response = ServiceHelper.GetIncomeRecords(item); 

我想你也必须使用svcutil.exe的命令生成代理类,然后编辑结果,剥离代理并仅留下请求/响应类及其支持类型。或者,如果您已经在VS中添加了“添加服务引用”,则可以单击解决方案资源管理器中的“显示所有文件”选项并钻取服务引用。其中一个文件包含生成的服务代理及其支持类型,全部在一个文件中。

+0

嗨@Ian,公司的方式是使用服务助手,使用预先构建的WCF代理帮助对象。扩展方法可以工作,但我如何重新创建或使客户端意识到GetAllIncomesRequest和其他对象?当我删除服务参考时,它们将消失。 – 2011-03-29 09:19:56