WCF - 如何在C#代码中指定终结点的契约?

3
我该如何在C#代码中指定合同?我想消除对配置文件的依赖,并出现错误:
“找不到默认终结点元素,该元素引用合同'TFBIC.RCT.HIP.Components.RCTBizTalk.WcfService_TFBIC_RCT_BizTalk_Orchestrations',可能是因为没有找到应用程序的配置文件,或者在客户端元素中没有找到与此合同匹配的终结点元素。”
<endpoint 
   address="http://nxwtest08bt1/TFBIC.RCT.BizTalk.Orchestrations/WcfService_TFBIC_RCT_BizTalk_Orchestrations.svc"
   binding="wsHttpBinding" 
   bindingConfiguration="WSHttpBinding_ITwoWayAsync"
   contract="TFBIC.RCT.HIP.Components.RCTBizTalk.WcfService_TFBIC_RCT_BizTalk_Orchestrations"
   name="WSHttpBinding_ITwoWayAsync">
   <identity>
      <userPrincipalName value="NXWTest08BT1\BTAdmin" />
   </identity>
</endpoint>

我第一次尝试使用ChannelFactory来指定通常隐藏在配置文件中的参数:

WSHttpBinding myBinding = new WSHttpBinding();

string webServiceURL = "http://localhost/TFBIC.RCT.BizTalk.Orchestrations/WcfService_TFBIC_RCT_BizTalk_Orchestrations.svc";
EndpointAddress myEndpoint = new EndpointAddress(webServiceURL);

ChannelFactory<WcfService_TFBIC_RCT_BizTalk_Orchestrations> myChannelFactory =
     new ChannelFactory<WcfService_TFBIC_RCT_BizTalk_Orchestrations>
         (myBinding, myEndpoint);

// Create a channel and call the web-service via the channel 
WcfService_TFBIC_RCT_BizTalk_Orchestrations wcfClient2 = 
                                       myChannelFactory.CreateChannel();
req.PolicyAction = polAction; 
resp = wcfClient2.WCFSubmitPolicyAction(req);
propResult = resp.PropertyValuation;

我正在使用Intellisense和myEndPoint变量,但是找不到像"contract"或者"bindingConfiguration"这样的东西。

我的做法是将我的.exe文件复制到一个新目录,并且完全删除<system.serviceModel>元素/组。我想尝试在没有配置文件的情况下运行。请参考我的相关问题:NUnit tests that call .DLLs that call WCF Web Services (.NET C#)。我试图跟随Gilham的答案,即使我并没有完全理解它。我认为学习ChannelFactory如何工作是第一步。

谢谢,

Neal Walters

附加配置文件部分:

<wsHttpBinding>
   <binding 
      name="WSHttpBinding_ITwoWayAsync" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
      bypassProxyOnLocal="false" transactionFlow="false" 
      hostNameComparisonMode="StrongWildcard" 
      maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
      messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
      allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" 
                    maxArrayLength="16384" maxBytesPerRead="4096" 
                    maxNameTableCharCount="16384" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00"
                       enabled="false" />;
      <security mode="Message">
         <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />;
         <message clientCredentialType="Windows" negotiateServiceCredential="true"
                  algorithmSuite="Default" establishSecurityContext="true" />
      </security>
   </binding>


2019年11月11日下午5点后进行编辑
根据@Marc_s的建议,我认为我终于弄清楚了,在定义通道工厂时将合同放入<channel>中。之前,我一直在寻找类似于endpoint.contract="xxx"的东西,因为在配置文件中,合同似乎是endpoint的子参数。

        //Not-Fully Qualified Contract 
        //ChannelFactory<WcfService_TFBIC_RCT_BizTalk_Orchestrations> myChannelFactory =
        //     new ChannelFactory<WcfService_TFBIC_RCT_BizTalk_Orchestrations>(myBinding, myEndpoint);
        //Fully Qualified Contract 
        ChannelFactory<TFBIC.RCT.HIP.Components.RCTWebService.WcfService_TFBIC_RCT_BizTalk_Orchestrations> myChannelFactory =
             new ChannelFactory<TFBIC.RCT.HIP.Components.RCTWebService.WcfService_TFBIC_RCT_BizTalk_Orchestrations>(myBinding, myEndpoint);

为了使上述内容编译通过,我还必须引用我的TBFIC.RCT.HIP.Components(我的.DLL类库调用WCF服务)。当我有配置文件时,尝试了上面的代码,它可以正常运行,但是当我删除配置文件时,仍然会出现以下错误:
“无法找到默认终结点元素,该元素引用合同“TFBIC.RCT.HIP.Components.RCTWebService.WcfService_TFBIC_RCT_BizTalk_Orchestrations”,该合同可能是因为未找到应用程序的配置文件,或者是因为在客户端元素中找不到与此合同匹配的终结点元素。”
现在,我仍然迷惑不解如何消除配置文件的依赖性。我现在使用的确切合同是通道工厂定义中缺失的合同。再次感谢!
2个回答

1

嗯,在用代码创建端点时,其结构与在配置文件中创建的并不完全相同。

例如,"Binding"类上没有"bindingConfiguration"设置 - 您需要明确设置该bindingConfiguration中的所有内容。

您能够展示一下那个部分吗?(您所提到的<bindingConfiguration>

当您创建通道工厂时,该契约即被定义 - 在我看来,这应该是可以的。

您收到的错误似乎表明,您的某些代码仍然尝试创建客户端代理类(最可能是使用"添加服务引用"或在命令行上使用svcutil.exe创建的),并且该代码尝试从配置文件中读取配置。

Marc

PS:我认为现在你应该没问题了 - 你创建了 wsHttpBinding 并使用了所有默认值(如配置文件中所示),你定义了端点地址指向托管服务的服务器,并在通道工厂中指定了正在使用的契约 - 就是这样。错误指向另一个“流氓”客户端代理,它仍然尝试从配置文件中读取 - 你是通过“添加服务引用”来添加引用的吗?如果是,请从项目中删除该服务引用。


我在我的上面的原始帖子底部发布了我认为您询问的内容。也许我需要一个ServiceHost对象,就像这里所示:http://msdn.microsoft.com/en-us/library/ms731925.aspx?但是我无法弄清它实际上如何使用。 - NealWalters
@Neal:那些都是默认值 - 所以你可以使用在代码中创建的wsHttpBinding对象。 - marc_s
@Neal:如果你在服务器端(即你的服务所托管的地方),那么是的,你需要一个ServiceHost来“托管”你的服务(正如其名称所示)。但我假设这是在客户端上,使用/调用服务-对吗?在这种情况下,你绝对是在正确地创建通道工厂和从中创建通道。这不是问题所在。 - marc_s
@Marc_s:好的,IIS是我的主机 - 我没有意识到那个对象是关于这个的。我不得不手动更改我的配置文件和生成的reference.cs中的合同(以完全限定名)。所以现在,我需要在客户端C#代码中指定相同的合同名称。 - NealWalters
@Marc_s:我用最新的实验更新了问题(从“the saga continues”开始)。 - NealWalters
显示剩余2条评论

0

我不知道这是否有可能,但您真的打算硬编码值,如端点URL、安全凭据等吗?在我看来,这似乎是一个非常糟糕的想法。

我们在这里所做的是使用ChannelFactory根据我们保存在配置文件中的值,在运行时生成代理。


这是我的目的:http://stackoverflow.com/questions/1711588/nunit-tests-that-call-dlls-that-call-wcf-web-services-net-c - NealWalters
这是另一个例子 - 我正在以服务的方式在HIS(Host Integration Server)下运行我的.DLL。刚刚,为了使它正常工作,我不得不添加一个app.config到Windows服务中。 - NealWalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接