WCF OperationContract 属性忘记值

发布于 2024-10-29 07:08:01 字数 1592 浏览 3 评论 0原文

最近成功让我的 IIS 托管的 WCF 服务使用基本身份验证

自从成功实施以来。我注意到属性值没有被记住。

这是一些代码:

[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
实际结果:你说:

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

点击此处下载。
我怎样才能让属性发挥作用?

谢谢

recently have been successful getting my IIS hosted WCF service to work with basic authentication.

Since successfully implementing that. I have noticed that property values are not remembered.

Here is some code:

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

Here is the console and the result:

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

Expected Result: You said: Hello World
Actual Result: You said:

I have Uploaded the sandbox project to my skydrive. I have included a SETUP.txt in the API project.

Click here to download.
How can I get properties to work?

thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅气尐潴 2024-11-05 07:08:01

我从未见过 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;}
}

虽然这改变了契约,但如果仔细管理的话,这样的改变可以向后兼容。

I have never seen WCF contract used with a property to transfer data. i.e. the Message property. AFAIK its just not possible.

My recommendation would be to keep the concerns that are part of the contract separate, i.e. Operation and Data.

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

Or

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

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

At some later point you may wish to change the Message Object.

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

While this changes the contract, changes like this can be backwardly compatible if managed carefully.

素年丶 2024-11-05 07:08:01

要了解发生的情况,您需要知道您所连接的服务对象的生命周期是如何配置的。 有关会话、实例化和并发的 MSDN 文章是一个很好的起点

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

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

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

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

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

    [OperationContract]
    string GetMessage();

    ... etc ...
}

To understand what's happening, you need to know how the lifetime of the service object you're connecting to is configured. A good starting point is the MSDN article on Sessions, Instancing, and Concurrency.

For example, with InstanceContextMode.PerCall, a new service object will be created for each call, so no properties of the service object will be remembered between calls.

At the other end of the scale, InstanceContextMode.Single means a single instance handles all client requests for the lifetime of the application. In this case properties set by one client will be visible to all clients, not usually desirable.

In general, I would recommend using a stateless service object. But if you want a stateful service object (e.g. one with properties), you should use InstanceContextMode.PerSession, and (important) use a binding that supports sessions.

While I agree with @JTew that you shouldn't generally expose operations as properties, you will have the same problem if you try to use an object that stores state between calls in another way (such as a private field). I.e. the following would have exactly the same problem:

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

    [OperationContract]
    string GetMessage();

    ... etc ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文