WCF OperationContract属性会忘记值

时间:2011-04-03 23:48:00

标签: c# .net wcf wcf-client

最近一直是successful getting my IIS hosted WCF service to work with basic authentication

自成功实施以来。我注意到房产价值不会被记住。

以下是一些代码:

[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:

我已将沙箱项目上传到我的skydrive。我在API项目中包含了一个SETUP.txt。

Click here to download.
我怎样才能让物业运作?

谢谢

2 个答案:

答案 0 :(得分:3)

我从未见过与资产一起使用的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 :(得分:1)

要了解发生了什么,您需要知道如何配置要连接的服务对象的生命周期。一个很好的起点是the MSDN article on Sessions, Instancing, and Concurrency

例如,使用InstanceContextMode.PerCall,将为每个调用创建一个新的服务对象,因此在调用之间不会记住服务对象的任何属性。

在比例的另一端,InstanceContextMode.Single表示单个实例处理应用程序生命周期内的所有客户端请求。在这种情况下,由一个客户端设置的属性对所有客户端都是可见的,通常不是所希望的。

一般情况下,我建议使用无状态服务对象。但是,如果您需要有状态服务对象(例如具有属性的对象),则应使用InstanceContextMode.PerSession,并且(重要)使用支持会话的绑定。

虽然我同意@JTew你通常不应该将操作公开为属性,但是如果你试图使用以另一种方式(例如私有字段)在调用之间存储状态的对象,则会遇到同样的问题。即以下将有完全相同的问题:

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

    [OperationContract]
    string GetMessage();

    ... etc ...
}