0

我有一个在 IIS 中托管的具有 2 个端点(1 个 webHttpBinding 和 1 个 basicHttpBinding)的 WCF 服务。客户端可以毫无问题地发出 http 请求。我能够通过 WCFTestClient 连接和调用 SOAP 端点,并且能够成功地将服务引用添加到我的客户端项目。问题是在 Reference.cs 文件或客户端上的 app.config 文件中没有生成代码……它们都是空的。

我的问题是,为什么我能够通过 WCFTestClient 而不是通过 Add Service Reference 方法毫无问题地连接和调用 SOAP 端点?

编辑:我在添加服务引用的程序集上的引用似乎是一个问题。我正在引用另一个类库(服务中存在相同的库),并且在构建解决方案时收到此警告:

Warning 12  Custom tool warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Referenced type 'MyNamespace.KPI.ChartObject`2, MyNamespace.KPI.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3e720b7e8a51f8d5' with data contract name 'ChartObjectOfdecimalZKPIPeriodaU4eboDJ' in namespace 'http://schemas.datacontract.org/2004/07/MyNamespace.KPI' cannot be used since it does not match imported DataContract. Need to exclude this type from referenced types.

需要注意的是,这个特定的类是一个泛型类...不知道这是否与错误有关。

4

2 回答 2

1

你需要遵循你的ABC:

  • 地址
  • 捆绑
  • 合同

通过 HTTP 公开的地址只需要一个部署 URL。互联网信息系统正在为您处理所有这些。然而; 如果您尝试在Service Reference没有正确定义的情况下使用 - 它不会显示。因为它没有去向的细节

一旦您定义了该标准,它应该按正常显示。


更新:

您可以将 SOAP 和 REST 从同一个服务合同中推向高潮,也可以将它们分开。在这个例子中;我会把它们分开。

创建服务:

[ServiceContract]
public interface IMath
{
      [OperationContract]
      int Add(int Number1, int Number2);
}

创建休息服务合同:

[ServiceContract]
public interface IMathRest
{

     [OperationContract]
     [WebGet(UriTemplate = "/Add/{Number1}/{Number2}", RequestFormat = WebMessageFormat.Json,
              ResponseFormat = WebMessageFormat.Json)]
     int AddRest(string Number1, string Number2);
}

在上述服务中;它明确设置消息格式。

实现服务:“绑定”

public class Math : IMath, IMathRest
{
     public int Add(int Number1, int Number2)
     {
         return Number1 + Number2;
     }

     public int AddRest(string Number1, string Number2)
     {
         int num1 = Convert.ToInt32(Number1);
         int num2 = Convert.ToInt32(Number2);
         return num1 + num2;
     }
}

配置服务:

<serviceBehaviors>
      <behavior name = "servicebehavior">
          <serviceMetadata httpGetEnabled = "true" />
          <serviceDebug includeExceptionDetailInFaults = "false" />
      </behavior>
</serviceBehaviors>

以上将服务设置为Basic / Web Http。

配置完成后,您serviceBehavior需要定义端点:

<endpointBehaviors>
     <behavior name="restBehavior">
          <webHttp/>
     </behavior>
</endpointBehaviors>

这会将您的 Rest Endpoint 配置为webHttpBinding上面指定的。现在你需要定义你的肥皂。

<endpoint name = "SoapEndPoint"
       contract = "Namespace in which Service Resides goes here"
       binding = "basicHttpBinding" <!-- Mirrors are above configuration -->
       address = "soap" />

以上将进入您的配置;但是在使用服务时,需要端点名称。端点将在基地址/肥皂地址处可用。使用的绑定是指定的。

除了我们只配置了我们的肥皂,而不是我们的休息。所以我们需要指定我们的端点:

<endpoint name = "RestEndPoint"
       contract = "Namespace that our Rest Interface is located goes here"
       binding = "webHttpBinding"
       address = "rest"
       behaviorCOnfiguration = "restBehavior" />

我们的 Rest Endpoint 将在我们的 Url(基地址/Rest/Add/Parameter/Parameter)处调用。我们已经指定了绑定;并设置我们的休息行为。

当你把整件事放在一起时;它看起来像:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name ="servicebehavior">        
          <serviceMetadata httpGetEnabled="true"/>        
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="restbehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name ="MultipleBindingWCF.Service1"
               behaviorConfiguration ="servicebehavior" >
        <endpoint name ="SOAPEndPoint"
                  contract ="MultipleBindingWCF.IService1"
                  binding ="basicHttpBinding"
                  address ="soap" />

        <endpoint name ="RESTEndPoint"
                  contract ="MultipleBindingWCF.IService2"
                  binding ="webHttpBinding"
                  address ="rest"
                  behaviorConfiguration ="restbehavior"/>

        <endpoint contract="IMetadataExchange"
                  binding="mexHttpBinding"
                  address="mex" />
      </service>
    </services>   
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer> 
</configuration>

消费:

使用我们的肥皂很简单;直截了当。制作服务参考并拨打电话。

static void CallingSoapFunction()
{
     SoapClient proxy = new SoapClient("SoapEndPoint");
     var result = proxy.Add(7,2); // Proxy opens the channel, we invoke our method, we input our parameters.
     Console.WriteLine(result);
}

除了我们的 Restful 消费略有不同;特别是因为我们必须将其格式化为 Json。所以我们需要准确地指定名称。

Rest 将依赖 Json 对数据进行反序列化。

static void CallRestFunc()
{
     WebClient RestProxy = new WebClient();
     byte[] data = RestProxy.DownloadData(new Uri("http://localhost:30576/MathRest.svc/Rest/Add/7/2")); // As you see it is following the exact location of the project, invoking method / parameter and so on down the line.
Stream stream = new MemoryStream(data);
DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(string));
string result = obj.ReadObject(stream).ToString();
Console.WriteLine(result);
}

以上将使用 Rest Uri 下载数据。反序列化该数据;并被展示出来。

希望这有助于澄清。

如果您的配置文件中没有创建正确的项目;那么它将不允许适当的消费。ABC 在 WCF 中至关重要。如果它不是在配置文件中创建的,您需要在代码中以编程方式创建它们。


更新:

static void Main(string[] args)
{
    var binding = new BasicHttpBinding();
    var endpoint = new EndpointAddress("http://localhost:8080/");
    using (var factory = new ChannelFactory<IPerson>(binding, endpoint))
    {
        var request = new Dictionary<Guid, Person>();
        request[Guid.NewGuid()] = new Person { Name = "Bob", Email = "Bob@abc.com" };

        var client = factory.CreateChannel();
        var result = client.SetCustomer(request);

        Console.WriteLine("Name: {0} | Email: {1}", result.Name, result.Email);
        factory.Close();
    }
    Console.ReadKey(true);
}

正如您在这个基本示例中看到的那样;绑定和端点都已配置。您需要确保所有这些都在您的服务器和客户端中定义。它必须知道它要去哪里。这更有意义吗?

于 2013-01-04T00:10:22.753 回答
0

看看这个网址。希望这对您有所帮助。

于 2013-11-11T10:03:37.423 回答