【问题标题】:WCF OperationContract property forgets valueWCF OperationContract 属性忘记值
【发布时间】:2011-04-03 23:48:00
【问题描述】:

最近一直是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.
我怎样才能让属性工作?

谢谢

【问题讨论】:

    标签: c# .net wcf wcf-client


    【解决方案1】:

    我从未见过与属性一起使用 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;}
    }
    

    虽然这会改变合同,但如果仔细管理,这样的更改可以向后兼容。

    【讨论】:

    • 感谢您确认我应该一起删除属性。
    【解决方案2】:

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

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

    在规模的另一端,InstanceContextMode.Single 意味着单个实例处理应用程序生命周期内的所有客户端请求。在这种情况下,由一个客户端设置的属性将对所有客户端可见,这通常是不可取的。

    一般来说,我会推荐使用无状态服务对象。但是如果你想要一个有状态的服务对象(例如一个有属性的对象),你应该使用 InstanceContextMode.PerSession,并且(重要的)使用支持会话的绑定。

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

    [ServiceContract]
    public interface IEcho
    {
        [OperationContract]
        void SetMessage(string message);
    
        [OperationContract]
        string GetMessage();
    
        ... etc ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 2020-08-14
      • 2015-09-25
      • 1970-01-01
      • 2017-12-26
      • 1970-01-01
      • 2013-01-15
      相关资源
      最近更新 更多