Свойство WCF OperationContract забывает значение - PullRequest
2 голосов
/ 04 апреля 2011

недавно было успешно получено, что мой WCF-сервис, размещенный на IIS, работает с базовой аутентификацией .

С тех пор, как это успешно реализованоЯ заметил, что значения свойств не запоминаются.

Вот код:

[ServiceContract]
public interface IEcho
{
    string Message { [OperationContract]get; [OperationContract]set; }
    [OperationContract]
    string SendEcho();
}

public class EchoProxy : IEcho
{
    public string Message { get; set; }
    public string SendEcho()
    {
        return string.Concat("You said: ", Message);
    }
}
public class EchoService : System.ServiceModel.ClientBase<IEcho>, IEcho
{
    //-- ..... CONSTRUCTORS OMITTED ....

    public string Message
    {
        get { return base.Channel.Message; }
        set { base.Channel.Message = value; }
    }
    public string SendEcho()
    {
        return base.Channel.SendEcho();
    }
}

Вот консоль и результат:

EchoService client = new EchoService("SecureEndpoint");
client.ClientCredentials.UserName.UserName = "test";
client.ClientCredentials.UserName.Password = "P@ssword1";
client.Message = "Hello World";
Console.WriteLine(client.SendEcho());

Ожидаемый результат: You said: Hello World
ФактическийРезультат: You said:

Я загрузил проект песочницы на мой переходник.Я включил SETUP.txt в проект API.

Нажмите здесь, чтобы загрузить.
Как мне заставить свойства работать?

спасибо

Ответы [ 2 ]

3 голосов
/ 04 апреля 2011

Я никогда не видел, чтобы контракт WCF использовался со свойством для передачи данных. то есть свойство Message. AFAIK это просто невозможно.

Моя рекомендация заключается в том, чтобы разделить проблемы, являющиеся частью контракта, т. Е. Операции и данные.

[ServiceContract]
public interface IEcho
{
    [OperationContract]
    string SendEcho(string Message);
}

или

[ServiceContract]
public interface IEcho
{
    [OperationContract]
    string SendEcho(Message message);
}

[DataContract]
public class Message
{
    [DataMember]
    public string Message {get; set;}
}

В более поздний момент вы можете изменить объект сообщения.

[DataContract]
public class MessageV2 : Message
{
    [DataMember]
    public DateTime Sent {get; set;}
}

Хотя это меняет контракт, такие изменения могут быть обратно совместимы, если им управлять осторожно.

1 голос
/ 04 апреля 2011

Чтобы понять, что происходит, вам нужно знать, как настроено время жизни сервисного объекта, к которому вы подключаетесь. Хорошей отправной точкой является статья MSDN о сеансах, экземплярах и параллелизме .

Например, с InstanceContextMode.PerCall будет создаваться новый объект службы для каждого вызова, поэтому свойства объекта службы не будут запоминаться между вызовами.

На другом конце шкалы InstanceContextMode.Single означает, что один экземпляр обрабатывает все клиентские запросы за время существования приложения. В этом случае свойства, установленные одним клиентом, будут видны всем клиентам, что обычно нежелательно.

В общем, я бы рекомендовал использовать объект службы без сохранения состояния. Но если вам нужен объект службы с состоянием (например, объект со свойствами), вы должны использовать InstanceContextMode.PerSession и (важно) использовать привязку, поддерживающую сеансы.

Хотя я согласен с @JTew в том, что вы вообще не должны представлять операции в качестве свойств, у вас будет та же проблема, если вы попытаетесь использовать объект, который хранит состояние между вызовами другим способом (например, частное поле). То есть следующее будет иметь точно такую ​​же проблему:

[ServiceContract]
public interface IEcho
{
    [OperationContract]
    void SetMessage(string message);

    [OperationContract]
    string GetMessage();

    ... etc ...
}
...