Consumed WCF service returns void although return type (& value) specified
I have a WCF service that I am attempting to connect to via a console application for testing (although will move to WPF for the final interface). I have generated the proxy, added the service reference to my project in visual studio and I can see all the methods I have created in my WCF interface:
SupportStaffServiceClient client = new SupportStaffServiceClient("WSHttpBinding_ISupportStaffService");
client.myMethod(message);
However when I call a method, which in the WCF interface is specified as returning a value, the method returns void in the console application.
client.getMethod(message);
The WCF service method is definitely returning a message, I'm just unsure as to why the client cannot "see" the return.
[service code]
[ServiceContract(Namespace="http://localhost/supportstaff")]
public interface ISupportStaffService
{
[OperationContract]
TutorMessage AddTutor(TutorMessage message);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class SupportStaff : ISupportStaffService
{
private ITutorService tutors;
public SupportStaff()
{
// Create the bind开发者_JAVA技巧ing
WSHttpBinding logBind = new WSHttpBinding();
// Create the channel factory to the logging service
ChannelFactory<ILogger> logFactory = new ChannelFactory<ILogger>(logBind, "http://localhost:8000/logger");
// Create the connection to the logging service
this.logger = logFactory.CreateChannel();
// Create the binding
WSHttpBinding tutorBind = new WSHttpBinding();
// Create the channel factory to the Tutor service
ChannelFactory<ITutorService> tutorFactory = new ChannelFactory<ITutorService>(tutorBind, "http://localhost:8001/tutors");
// Create the connection to the Tutor service
this.tutors = tutorFactory.CreateChannel();
}
TutorMessage ISupportStaffService.AddTutor(TutorMessage message)
{
// First log that we have received an add Tutor message
// Create a log message
LogMessage logMessage = new LogMessage();
logMessage.Time = message.Time;
logMessage.Message = "[Supprt Staff Service] Add Tutor message received";
// Send the log message to the logging service
logger.Log(logMessage);
// Create a request to add the Tutor to the Tutor service
TutorMessage request = new TutorMessage();
request.Time = DateTime.Now;
request.Tutor = message.Tutor;
// Send the add Tutor message to the Tutor message
tutors.AddTutor(request);
// Display the message
Console.WriteLine("Added Tutor " + message.Tutor.Number);
// Log the message
logMessage = new LogMessage();
logMessage.Time = DateTime.Now;
logMessage.Message = "[Support Staff Service] Added Tutor " + message.Tutor.Number;
logger.Log(logMessage);
// Create the return message
TutorMessage toReturn = new TutorMessage();
toReturn.Time = DateTime.Now;
toReturn.Tutor = message.Tutor;
// Return the return message
return toReturn;
}
}
[ServiceContract(Namespace = "http://localhost/tutors")]
public interface ITutorService
{
[OperationContract]
void AddTutor(TutorMessage message);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class TutorService : ITutorService
{
private Dictionary<string, Tutor> tutors = new Dictionary<string, Tutor>();
void ITutorService.AddTutor(TutorMessage message)
{
// First log the fact that we have received an Add message
// Create the log message
LogMessage logMessage = new LogMessage();
logMessage.Time = message.Time;
logMessage.Message = "[Tutor Service] Tutor add message received";
// Send the log message to the logging service
logger.Log(logMessage);
// Now add the new Tutor to the collection of Tutors
tutors[message.Tutor.Number] = message.Tutor;
// Display message that Tutor is added
Console.WriteLine("Added tutor : " + message.Tutor.Number);
// Log the new Tutor
logMessage = new LogMessage();
logMessage.Time = DateTime.Now;
logMessage.Message = "[Tutor Service] Added tutor : " + message.Tutor.Number;
logger.Log(logMessage);
}
}
[client code]
class Program
{
static void Main(string[] args)
{
SupportStaffServiceClient client = new SupportStaffServiceClient("WSHttpBinding_ISupportStaffService");
try
{
localhost.tutor.tutor t1 = new localhost.tutor.tutor();
t1.name = "Big Dave";
t1.number = "t123";
DateTime time = DateTime.Now;
client.AddTutor(ref time, ref t1);
localhost.tutor.tutor t2 = new localhost.tutor.tutor();
client.RetrieveTutor(ref time, ref t1);
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message.ToString());
}
finally
{
Console.WriteLine("Press <RETURN> to exit");
Console.ReadLine();
}
}
}
[svcutil generated code]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class SupportStaffServiceClient : System.ServiceModel.ClientBase<ConsoleApplication1.SupportStaffService.ISupportStaffService>, ConsoleApplication1.SupportStaffService.ISupportStaffService {
public SupportStaffServiceClient() {
}
public SupportStaffServiceClient(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public SupportStaffServiceClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public SupportStaffServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public SupportStaffServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
public string HelloWorld(string name) {
return base.Channel.HelloWorld(name);
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
ConsoleApplication1.SupportStaffService.TutorMessage ConsoleApplication1.SupportStaffService.ISupportStaffService.AddTutor(ConsoleApplication1.SupportStaffService.TutorMessage request) {
return base.Channel.AddTutor(request);
}
public void AddTutor(ref System.DateTime time, ref ConsoleApplication1.SupportStaffService.tutor tutor) {
ConsoleApplication1.SupportStaffService.TutorMessage inValue = new ConsoleApplication1.SupportStaffService.TutorMessage();
inValue.time = time;
inValue.tutor = tutor;
ConsoleApplication1.SupportStaffService.TutorMessage retVal = ((ConsoleApplication1.SupportStaffService.ISupportStaffService)(this)).AddTutor(inValue);
time = retVal.time;
tutor = retVal.tutor;
}
}
I've never seen svcutil
generate a method with ref
parameters before - how did it do that? Anyway, it looks like you want to call the method above that in the generated code - this one takes and returns a TutorMessage
object. So you could do
TutorObject returnedTutor = client.AddTutor(inputTutorObject);
Or, it looks like if you call the method with the ref
parameters, as you're currently doing, the "return" value is put into those same ref parameters. So you pass in time
and t1
, call AddTutor
, and now those variables you've passed in will contain the returned values. So, you could do
t1.name = "Big Dave";
t1.number = "t123";
DateTime time = DateTime.Now;
client.AddTutor(ref time, ref t1);
// time now contains the returned DateTime from the service
// t1 now contains the returned Tutor from the service
I had a similar problem where we'd forgottent to mark a custom MessageContract
on our Response Class with the MessageBodyMemberAttribute
our messageResponse Class didn't expose any members in it's data contract thus the Call to the service returned void.
Before...
[MessageContract]
public class MyCustomResponse
{
public string Response { get; set; }
}
...
After...
[MessageContract]
public class MyCustomResponse
{
[MessageBodyMember(Namespace = "http://MyNamespace")]
public string Response { get; set; }
}
After adding the MessageBodyMember
to the Response member, the svcutil generates code that hides the details of the custom Message Contract and just returns the Response as a string return value from my service's proxy.
I had the same problem with outer service (couldn't change its notation). I've added /mc parameter to svcutil - it helped.
精彩评论