English 中文(简体)
WCF:服务在发送完整字符串后接收到“null”字符串
原标题:WCF : Service receiving "null" string after being sent a full string
  • 时间:2011-11-21 14:53:54
  •  标签:
  • 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);

    }
}
问题回答

though I dont know what is your issue may be something wrong with your generate code Here is full working example for sending a string from client and then receiving it from server.

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 
 " + d.MyString);

      Console.ReadLine();
    }
  }
}

更新:在没有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 
 " + 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 
 " + d);

      Console.ReadLine();

      Console.ReadLine();
    }
  }
}

显然,我对WCF接口的工作方式存在误解。

As you can see in my code, interface "IServiceOrder" is defined twice. Both on Client AND server side. Surjit Samra s code contained only one definition for the interface, and Ralf s Sudelbücher s example defined it only once in "WCFSimple.Contract" namespace. The fact that the interface was defined twice was what caused the service to "fail" in a very peculiar way.

If somebody could give a thorough explanation on why this double interface definition causes this behaviour, that would be good.

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

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

使用旧引用名称的原因是,每当我们创建web服务引用时,都会创建一个引用文件。即使我们更新/配置web服务,旧的引用名称也将保留在引用文件中。当您完全删除和添加服务引用时,将创建一个新的引用文件,之后的值将不为null。这就是解决方案

I think the problem is that you forgot to include the attribute [DataMember] I suggest that you use proper class object to serve as your parameter. In that way it represented in a well formed object.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签