【问题标题】:How to re-write WCF client to use ChannelFactory instead of service reference如何重写 WCF 客户端以使用 ChannelFactory 而不是服务引用
【发布时间】:2011-03-29 07:59:43
【问题描述】:

我有一个使用 web service software factory 创建的 WCF 服务。我所有的传入请求和返回的响应都作为消息契约实现。我一直在通过在 VS 中添加服务引用来访问该服务,效果很好。然而,我现在被告知这不是标准的公司方式,我需要使用基于 System.ServiceModel.ChannelFactory 的内部 WCF 代理帮助程序类来调用服务。

我以前从未使用过 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 中使用吗?

【问题讨论】:

    标签: wcf wcf-client


    【解决方案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 中完成了“添加服务引用”,则可以单击解决方案资源管理器中的“显示所有文件”选项并深入了解服务引用。其中一个文件包含生成的服务代理及其支持类型,都在一个文件中。

    【讨论】:

    • 嗨@Ian,是的,公司的方法是使用使用预构建的 WCF 代理助手对象的服务助手。扩展方法可以工作,但我如何重新创建或让客户端知道 GetAllIncomesRequest 和其他对象?当我删除服务引用时,它们就会消失。
    猜你喜欢
    • 1970-01-01
    • 2011-06-29
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    相关资源
    最近更新 更多