WCF:服务在发送完整字符串后接收“null”字符串

时间:2011-11-21 14:53:55

标签: c# wcf

我正在开发一个非常简单的WCF示例,但是我很难在服务器端检索从客户端发送的字符串值。我的代码非常基本。如果有人能带我到轨道去看看,我会非常感激(请原谅我有限的WCF知识)

编辑:有趣的是,我可以从服务器返回客户端的返回值!
(见下面的修改代码)

客户代码:

    public void SendData()
    {
        string rogerback = proxy.SendData("String To Be Delivered");
        Console.Writeline(rogerback); //<--Prints "PICKABOO" 
    }

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "IServiceOrder")]
    public interface IServiceOrder
    {
        [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IServiceOrder/SendData")]            
        string SendData(string data);
    }

服务器代码:

[ServiceContract]
public interface IServiceOrder
{
    [OperationContract]
    string SendData(string data);        
}

public class ServiceOrder : IServiceOrder
{     
    public string SendData(string value)
    {

        if (value== null) Console.WriteLine("value IS NULL"); //<--Always the case when I execute Client code SendData()
        return "PICKABOO";
        //return value <-- returns null
        doSomething(value);

    }
}

4 个答案:

答案 0 :(得分:2)

虽然我不知道你的问题是什么,但你的生成代码可能有问题 以下是从客户端发送字符串然后从服务器接收字符串的完整工作示例。

using System;
using System.Runtime.Serialization;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace MySpace
{

  [DataContract]
  public class Data
  {
    [DataMember]
    public string MyString;

  }
  [ServiceContract]
  public interface IService
  {
    [OperationContract]
    Data Method(Data dd);
  }

  public class Service : IService
  {
    public Data Method(Data dd)
    {
      dd.MyString = dd.MyString + " String from Server.";
      return dd;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      string Url = "http://localhost:8000/";
      Binding binding = new BasicHttpBinding();
      ServiceHost host = new ServiceHost(typeof(Service));
      host.AddServiceEndpoint(typeof(IService), binding, Url);
      host.Open();
      ChannelFactory<IService> fac = new ChannelFactory<IService>(binding);
      fac.Open();
      IService proxy = fac.CreateChannel(new EndpointAddress(Url));
      Data d = new Data();
      d.MyString = "String from client.";
      d = proxy.Method(d);
      fac.Close();
      host.Close();
      Console.WriteLine("Result after calling \n " + d.MyString);

      Console.ReadLine();
    }
  }
}

更新:通过传递字符串工作fab

来运行没有DataContract的代码
using System;
using System.Runtime.Serialization;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace MySpace
{
  [ServiceContract]
  public interface IService
  {
    [OperationContract]
    string Method(string dd);
  }

  public class Service : IService
  {
    public string Method(string dd)
    {
      dd  =dd+ " String from Server.";
      return dd;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      string Url = "http://localhost:8000/";
      Binding binding = new BasicHttpBinding();
      ServiceHost host = new ServiceHost(typeof(Service));
      host.AddServiceEndpoint(typeof(IService), binding, Url);
      host.Open();
      ChannelFactory<IService> fac = new ChannelFactory<IService>(binding);
      fac.Open();
      IService proxy = fac.CreateChannel(new EndpointAddress(Url));


      string d = proxy.Method("String from client.");
      fac.Close();
      host.Close();
      Console.WriteLine("Result after calling \n " + d);

      Console.ReadLine();
    }
  }
}

更新3我仍然认为您生成的代码/代理有问题,因为这是使用客户端/服务器上的不同接口进行测试(如果您的问题已经解决,您可以忽略它的任何方式:)

using System;
using System.Runtime.Serialization;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

namespace MyClient
{
  [ServiceContract]
  public interface IService
  {
    [OperationContract]
    string Method(string dd);
  }
}

namespace MyServer
{
  [ServiceContract]
  public interface IService
  {
    [OperationContract]
    string Method(string dd);
  }
}

namespace MySpace
{  
  public class Service :MyServer.IService
  {
    public string Method(string dd)
    {
      dd  =dd+ " String from Server.";
      return dd;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      string Url = "http://localhost:8000/";
      Binding binding = new BasicHttpBinding();
      ServiceHost host = new ServiceHost(typeof(Service));
      host.AddServiceEndpoint(typeof(MyServer.IService), binding, Url);
      host.AddDefaultEndpoints();
      host.Open();

      ChannelFactory<MyClient.IService> fac = new ChannelFactory<MyClient.IService>(binding);
      fac.Open();
      MyClient.IService proxy = fac.CreateChannel(new EndpointAddress(Url));


      string d = proxy.Method("String from client.");
      fac.Close();
      host.Close();
      Console.WriteLine("Result after calling \n " + d);

      Console.ReadLine();

      Console.ReadLine();
    }
  }
}

答案 1 :(得分:1)

显然,我的方面存在一种误解,关于WCF接口如何工作。

正如您在我的代码中所看到的, 接口“IServiceOrder”定义了两次 。客户端和服务器端的 。 Surjit Samra的代码只包含一个接口定义,Ralf's Sudelbücher's example在“WCFSimple.Contract”命名空间中只定义了一次。 接口定义两次的事实是导致服务以非常特殊的方式“失败”的原因。

如果有人能够详细解释为什么这个双接口定义会导致这种行为,那就太好了。

基本上,我选择这样做是因为我希望我的客户端完全不了解服务器实现。但我误导了,因为客户端和服务器都需要查看AND访问 接口(即合同)定义。我想这就是它的工作原理。

答案 2 :(得分:0)

如果您已添加服务引用,请完全删除该服务引用。新添加服务引用到您的客户端应用程序并运行该应用程序。

旧引用名称的原因是,每当我们创建Web服务引用时,都将创建引用文件。尽管我们更新/配置了Web服务,但旧的引用名称将在参考文件中得到维护。当您完全删除并添加服务引用时,将创建一个新的引用文件,在该值之后不会为null。这是解决方案

答案 3 :(得分:0)

我认为问题是你忘了包含属性[DataMember] 我建议您使用适当的类对象作为参数。 以这种方式,它代表了一个形成良好的对象。