2011-04-03 54 views
2

最近一直是successful getting my IIS hosted WCF service to work with basic authenticationWCF OperationContract属性忘记值

由于成功地实现了。我注意到财产价值不被记住。

下面是一些代码:

[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 = "[email protected]"; 
client.Message = "Hello World"; 
Console.WriteLine(client.SendEcho()); 

预期结果:You said: Hello World
实际结果:You said:

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

Click here to download.
我该如何获取属性才能工作?

谢谢

回答

3

我从来没有见过一个属性用来传输数据的WCF的合同。即消息属性。 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

谢谢您确认我shuold一起删除属性。 – 2011-04-04 04:22:11

1

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

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

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

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

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

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

    [OperationContract] 
    string GetMessage(); 

    ... etc ... 
} 
+0

谢谢你这个信息! – 2011-04-05 04:58:49