如何仅使用App.config数据创建WCF客户端?

时间:2014-10-28 16:55:13

标签: c# wcf web-config app-config

我必须连接到不响应svcutil的WCF服务,并且不允许我使用Visual Studio中的自动化工具创建服务引用 - 编写/托管WCF服务的人员是非常安全意识,并已禁用这些功能(为什么,我不知道)。

我只获得了配置数据。

我的问题是:开发可以向此服务发送WCF请求的客户端的下一步是什么?

很抱歉这个开放式问题...我真的很难过,因为这不适合我在在线教程或TechNet文档中找到的任何场景。我是WCF的新手,所以我不知道从哪里开始。

返回类型是可通过键/值对访问的数据集,但我不确定C#数据类型是什么。我给出的文档说的是KeyValueOfstringPropertyDto3azeXyb8。提到了EntityDto,但我不熟悉这个(EntityFramework术语?)。我已经在返回数据集中提供了列的列表,但出于安全原因,我无法直接在问题中发布列名。

服务名称和绑定:
名称:RecordFindSingle
网址:http://Server01/RecordFindSingle/RecordFindSingle.svc
方法:FindSingleRecord
参数1:来源
参数2:RecordNumber

<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_ITwoWayAsync" maxReceivedMessageSize="2147483647">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows" />
            <message clientCredentialType="Username" />
          </security>
        </binding>
       </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://Server02/RecordFindSingle/RecordFindSingle.svc"
          binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITwoWayAsync"
          contract="RecordFindSingle.RecordFindSingle" name="BasicHttpBinding_ITwoWayAsync" />
    </client>
  </system.serviceModel>
</configuration>

2 个答案:

答案 0 :(得分:1)

您可以在运行时使用HttpWebRequest来调用Web服务。为此,您不必在解决方案或项目中添加任何服务引用。在我的一个应用程序中,我使用此功能从MVC 4 Web API项目调用WCF Web服务。

实际上,您可以直接将SOAP发送到WCF服务,而无需创建代理类。只需创建一个WebClient对象并设置“Content-Type”和“SOAPAction”标头,然后将SOAP消息上传到服务。代码如下所示:

using (var client = new WebClient())
{
    var data = CreateSoapsEnvelope();
    client.Headers.Add("Content-Type", "text/xml;charset=utf-8");
    client.Headers.Add("SOAPAction", "\"tempuri.org/IMyService/MyOperation\"");
    var response = client.UploadString("localhost:1234/MyService.svc", data);
    Console.WriteLine(response);
}

其中CreateSoapsEnvelope()是创建Soap Envelope的函数,其中包含用于调用Web服务的输入参数

<s:Envelope xmlns:s="schemas.xmlsoap.org/soap/envelope/">;
    <s:Body> <OperationName xmlns="tempuri.org/">;
        <Inputparam1>Maged</Inputparam1> <Inputparam2>maged@mail.com</Inputparam2>
</OperationName> </s:Body> </s:Envelope>

答案 1 :(得分:1)

您必须创建一个定义服务合同的接口和相关DataContract。例如,如果您有Contract定义了FindSingleRecord方法,该方法返回Record的实例:

[DataContract]
public class Record
{
    [DataMember]
    public string Property1 {get;set;}
    [DataMember]
    public string Property2 {get;set;}

    // Continue listing all properties ...
}

[ServiceContract]
public interface RecordFindSingle
{
    [OperationContract]
    Record FindSingleRecord(string Source , int RecordNo);
}

然后使用频道工厂调用它:

var httpBinding = new BasicHttpBinding()
{
    Security = new BasicHttpSecurity()
    {
        Mode = BasicHttpSecurityMode.TransportCredentialOnly,
        Message = new BasicHttpMessageSecurity() { ClientCredentialType = BasicHttpMessageCredentialType.UserName },
        Transport = new HttpTransportSecurity() { ClientCredentialType = HttpClientCredentialType.Windows }
    }
};
ChannelFactory<RecordFindSingle> factory = new ChannelFactory<RecordFindSingle>(httpBinding, new EndpointAddress("http://Server02/RecordFindSingle/RecordFindSingle.svc"));
var channel = factory.CreateChannel();
Record result = channel.FindSingleRecord();