WCF 服务调用在每次调用中都包含相同的信息

发布于 2024-12-07 22:14:58 字数 847 浏览 1 评论 0原文

我有一个将由某些应用程序(当前是网站)使用的网络服务。

这些调用几乎都是特定于某个客户端的,但仍然是相同的。因此,一个调用可能是 getAllFoo() 但我需要一些参数来说明 Foo 是来自哪个客户端。

如果我只是向所有调用添加一个标准参数,它很快就会变得很麻烦,所以我希望做得有点干且自动。所有服务调用中都会包含一些内容。

IDispatchMessageInspector 适合我吗?其中可以包含哪些类型的信息?我可以在方法中访问该信息吗?

我应该为调用创建某种属性吗?

如果有人能指出我的解决方案,那就太好了。

编辑

我正在考虑的另一个解决方案。

当对特定客户端的服务调用发生在消费者端时,它将在instanceCreation 中得知,因此我可以使用已知的客户端来实例化ServiceClient。

我可以以某种方式将此解决方案用于 ClientBase 扩展程序吗?

假设我正在为 Domain1 提供服务(让我们调用客户端域,以免将其与服务客户端/消费者混淆),我创建一个 InformationProvider 消费者端,它有一个 ClientBase场地。我确保在构造时设置 DomainName (domain1),以便在实例化 ClientBase时我可以做同样的事情,这样它就以某种方式让服务知道我正在调用哪个域。

我仍在学习 WCF,所以我不确定如何做到这一点。

I have a web service that will be consumed by some application (web site currently).

The calls are almost all specific to a certain client but still the same. So one call might be getAllFoo() but I would need some parameter to say from which client the Foo is.

It would become bothersome quickly if I just add a standard parameter to all calls so I was hoping to do it a little bit DRY and automatic. Something that would be included in all service calls.

Is IDispatchMessageInspector the right thing for me here? What kind of info could that include and can I access that info inside the methods?

Should I create some sort of attribute perhaps for the calls?

If anyone could point me towards a solution for this it would be great.

Edit

Another solution I'm thinking off.

Where the service call to a specific client happens on the consumer side, it will be known at instanceCreation so I could instance the ServiceClient with a known client.

Could I use this solution for the ClientBase<> extender somehow.

Let's say I'm serving Domain1 (let's call the client Domain to not confuse it with a serviceclient/consumer) I create a InformationProvider consumer side that has a ClientBase<IInformationService> field. I ensure that the DomainName (domain1) is set at construction so I could parhaps do the same thing when instancing the ClientBase<IInformationService> so It somehow let's the service know what domain I'm calling for.

I'm just still learning about WCF so I'm not sure how one would do this.

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

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

发布评论

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

评论(2

岁吢 2024-12-14 22:14:58

我可以理解您想让解决方案保持简单和整洁,但最终 - 正如您自己所说 -

...我需要一些参数来说明来自哪个客户端...

最明显且最简单的解决方案是在需要的所有服务调用中包含 client 参数。当然,会有不需要客户端参数的服务调用,在这些情况下,您不需要包含该参数。

您也许可以做一些聪明的事情,在幕后谨慎地传递客户端标识符,但要小心不要做不必要的聪明的事情。我会将客户端作为简单参数传递,因为它被用作参数。我想到两个原因:

  1. 如果有人维护您的代码,他们很快就会明白发生了什么。
  2. 如果有人需要使用该服务,那么如何使用它是显而易见的。

I can understand that you want to keep you solution simple and tidy, but ultimately - as you say yourself -

... I would need some parameter to say from which client...

The obvious and simplest solution is to include a client parameter on all your service calls where it is required. Surely there'll be service calls that don't require the client parameter, and in those cases you don't need to include the parameter.

You may be able to do something clever where a client identifier is passed discreetly under the covers, but beware of doing unnecessarily clever things. I would pass the client as a simple parameter because it is being used as a parameter. Two reasons come to mind:

  1. if someone maintains your code they quickly understand what's going on.
  2. if someone needs to use the service it is obvious how to use it.
绿光 2024-12-14 22:14:58

一种可能的模式:

  • 确保每个会话都实例化服务。这意味着您必须使用 wsHttpBinding、netTcpBinding 或自定义绑定,因为 http 不支持会话。
  • 实例化每个会话时,始终调用初始化操作来设置该服务的客户端 ID。
  • 将此初始化操作放入代理的构造函数中。

涉及的步骤如下:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MyService : IMyService
{
    private int clientId;

    public void StartUp(int clientId)
    {
        this.clientId = clientId;

然后客户端,假设您使用生成的代理,将客户端包装在另一个代理内。

public class ExtendedClient : MyServiceClient
{
    public ExtendedClient(int clientid) : base()
    {
        this.StartUp(clientid);
    }

现在您应该实例化 ExtendedClient,它将创建通道并通过提供客户端 ID 来启动服务。

我个人更喜欢简单地为每个服务调用发送客户端 ID,但如果您能够使用可会话绑定,那么这应该可以工作。


只是为您提供一些有关 WCF 的信息。如果您有无状态服务,那么您需要在每个服务调用中包含客户端作为参数。这并不意味着您需要在整个代码中的任何地方都包含客户端 - 例如,您可以在 ClientBase 构造函数中检索它。但您需要将其添加到每个 OperationContract 和所有服务实现中。

另一种方法是拥有有状态服务 - 您第一次使用的实例将保留供您重用(超时/异常除外)。在这种情况下,您可以只发送客户端一次,然后服务将了解客户端以进行后续调用。这就是上面描述的模式。这意味着您不能使用 http 绑定。我相信,这样做只会增加应用程序中出现问题的可能性(有状态服务,必须确保初始化操作完成,进行更多的服务调用)。

A possible pattern:

  • Make sure you service instantiates per session. This means you'll have to use wsHttpBinding, netTcpBinding, or a custom binding as http does not support sessions.
  • Always call an initialization operation when each session is instantiated that sets the client id for that service.
  • Put this initialization operation inside a constructor for a proxy.

The steps involved would be something like this:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MyService : IMyService
{
    private int clientId;

    public void StartUp(int clientId)
    {
        this.clientId = clientId;

and then client side, assuming you use the generated proxy, wrap the client inside another proxy.

public class ExtendedClient : MyServiceClient
{
    public ExtendedClient(int clientid) : base()
    {
        this.StartUp(clientid);
    }

Now you should instantiate the ExtendedClient, it will create the channel and prime the service by delivering the client id.

I would personally prefer to simply send the client id for each service call, but if you are able to use a session-able binding then this should work.


Just some information on WCF for you. If you have a stateless service, then you'll need to include the client as a parameter in every service call. This does not mean you need to include the client everywhere throughout your code - you could, for example, retrieve it inside the ClientBase constructor. But you will need to add it to every OperationContract and all the service implementations.

The alternative is to have a stateful service - the instance that you first use will remain for you to reuse (except for timeouts / exceptions). In this case you can potentially send the client just once, and then the service will know about the client for subsequent calls. This is the pattern described above. It means that you cannot use http binding. I believe that by doing this you're only increasing the potential for problems in your application (stateful services, having to ensure the initialization operation completes, more service calls being made).

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