Использованный сервис WCF возвращает void, хотя указан тип возврата (& value) - PullRequest
1 голос
/ 26 марта 2010

У меня есть служба WCF, к которой я пытаюсь подключиться через консольное приложение для тестирования (хотя для окончательного интерфейса перейду в WPF). Я сгенерировал прокси, добавил ссылку на сервис в свой проект в visual studio и вижу все методы, которые я создал в своем интерфейсе WCF:

SupportStaffServiceClient client = new SupportStaffServiceClient("WSHttpBinding_ISupportStaffService");
client.myMethod(message);

Однако когда я вызываю метод, который в интерфейсе WCF указан как возвращающий значение, метод возвращает void в консольном приложении.

client.getMethod(message);

Метод службы WCF однозначно возвращает сообщение, я просто не уверен, почему клиент не может «увидеть» возврат.

[код услуги]

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

[код клиента]

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 сгенерированный код]

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

Ответы [ 3 ]

2 голосов
/ 26 марта 2010

Я никогда не видел, чтобы svcutil генерировал метод с ref параметрами раньше - как он это сделал? В любом случае, похоже, что вы хотите вызвать метод, описанный выше, в сгенерированном коде - этот метод принимает и возвращает объект TutorMessage. Так что вы могли бы сделать

TutorObject returnedTutor = client.AddTutor(inputTutorObject);

Или, похоже, если вы вызываете метод с параметрами ref, как вы это делаете в настоящее время, возвращаемое значение помещается в те же параметры ref. Таким образом, вы передаете time и t1, вызываете AddTutor, и теперь те переменные, которые вы передали, будут содержать возвращаемые значения. Итак, вы могли бы сделать

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
0 голосов
/ 29 ноября 2012

У меня была такая же проблема с внешним сервисом (я не мог изменить его обозначения). Я добавил параметр / mc в svcutil - это помогло.

0 голосов
/ 22 июля 2010

У меня была похожая проблема, когда мы забыли пометить пользовательский MessageContract в нашем классе ответа с помощью MessageBodyMemberAttribute, который наш класс messageResponse не предоставил ни одному члену в своем контракте данных, таким образом, вызов службы вернулся void .

До ...

[MessageContract]
public class MyCustomResponse
{
    public string Response { get; set; }
}
...

После того, как ...

[MessageContract]
public class MyCustomResponse
{
    [MessageBodyMember(Namespace = "http://MyNamespace")]
    public string Response { get; set; }
}

После добавления MessageBodyMember к члену Response svcutil генерирует код, который скрывает детали пользовательского контракта на сообщения и просто возвращает ответ как строковое возвращаемое значение из прокси-сервера моей службы.

...