WCF: service receives a "null" string after sending the full string

I am developing a very simple WCF example, but I can’t get the server-side string value that I send from the client side. My code is very simple. If anyone could lead me to tracks that could fix this, I would be very grateful (And please forgive my limited knowledge of WCF)

EDIT: The funny part is that I can get the return value in the client from the server!
(see modified code below)

Client Code:

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); } 

Server Code:

 [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
source share
4 answers

although I don’t know what your problem is, maybe something is wrong with your generation code Here is a complete working example for sending a string from a client and then receiving it from the 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 \n " + d.MyString); Console.ReadLine(); } } } 

Update: running code without DataContract, just passing the string, it works fab

 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(); } } } 

Update 3 I still think that something is wrong with your generated code / proxy as here, this is a test with different interfaces on the client / server (any way to ignore it if your problem has already been resolved :)

 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(); } } } 
+2
source

Apparently, for my part, there is a misconception about how WCF interfaces work.

As you can see in my code, the "IServiceOrder" interface is defined twice . Both on the client side, and on the server side. Surjit Samra code contained only one definition for an interface, and the Ralf Sudelbücher example defined it only once in the WCFSimple.Contract namespace. The fact that the interface was defined twice was the reason that the service "failed" very unusual.

If someone could give a detailed explanation of why this dual interface definition causes this behavior, that would be nice.

Basically, I decided to do this because I wanted my client to be completely agnostic in the server implementation. But I was misled, as both the client and the server must see AND gain access to the definition of one interface (for example, a contract). I think it works.

+1
source

If you have already added a link to the service, completely remove this link to the service. add the service link to your client application and run the application.

The reason for the old link name is that whenever we create a link to a web service, a link file will be created. Although we update / configure the web service, the old link name will be supported in the link file. When you completely delete and add a link to the service, a new link file will be created, after which the values ​​will not be zero. This decision

0
source

I think the problem is that you forgot to include the [DataMember] attribute. I suggest you use the correct class object, which will serve as your parameter. Thus, he is represented in a well-formed object.

0
source

Source: https://habr.com/ru/post/1382293/


All Articles