WCF服务调用在每个调用中包含相同的信息
我有一个web服务,它将被某些应用程序(当前的web站点)使用 这些调用几乎都是特定于某个客户机的,但仍然是相同的。因此,一个调用可能是getAllFoo(),但我需要一些参数来说明Foo来自哪个客户机 如果我只是在所有调用中添加一个标准参数,它会很快变得麻烦,所以我希望这样做有点枯燥和自动化。将包含在所有服务调用中的内容 IDispatchMessageInspector适合我吗?哪些类型的信息可以包含,我可以在方法中访问这些信息吗 我是否应该为调用创建某种属性 如果有人能为我指出解决这个问题的办法,那就太好了 编辑 我正在考虑另一个解决办法 当对特定客户机的服务调用发生在消费者端时,它将在instanceCreation中被知道,因此我可以用一个已知的客户机来实例ServiceClient 我是否可以将此解决方案用于WCF服务调用在每个调用中包含相同的信息,wcf,web-services,dry,Wcf,Web Services,Dry,我有一个web服务,它将被某些应用程序(当前的web站点)使用 这些调用几乎都是特定于某个客户机的,但仍然是相同的。因此,一个调用可能是getAllFoo(),但我需要一些参数来说明Foo来自哪个客户机 如果我只是在所有调用中添加一个标准参数,它会很快变得麻烦,所以我希望这样做有点枯燥和自动化。将包含在所有服务调用中的内容 IDispatchMessageInspector适合我吗?哪些类型的信息可以包含,我可以在方法中访问这些信息吗 我是否应该为调用创建某种属性 如果有人能为我指出解决这个问题
ClientBase
扩展器
假设我在服务域1(我们调用客户端域以避免将其与服务客户端/消费者混淆),我创建了一个InformationProvider
消费者端,它有一个ClientBase
字段。我确保域名(domain1)设置为construction,这样我可以在实例化ClientBase
时执行相同的操作,这样它就可以让服务知道我在调用哪个域
我仍在学习
WCF
,因此我不确定如何做到这一点。我可以理解,您希望保持解决方案简单整洁,但最终-正如您自己所说-
。。。我需要一些参数来说明从哪个客户端
最明显、最简单的解决方案是在所有需要的服务调用中包含client
参数。当然会有不需要客户机参数的服务调用,在这些情况下,您不需要包含参数
在客户机标识符被秘密传递的情况下,您可能可以做一些聪明的事情,但要注意不要做不必要的聪明事情。我会将客户机作为一个简单的参数传递,因为它正被用作一个参数。我想到两个原因:
- 确保每个会话都有服务实例化。这意味着您必须使用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构造函数中检索它。但您需要将其添加到每个
操作契约和所有服务实现中
另一种选择是拥有一个有状态服务——您第一次使用的实例将保留供您重用(超时/异常除外)。在这种情况下,您可以只发送一次客户机,然后服务将在后续调用中了解客户机。这就是上面描述的模式。这意味着您不能使用http绑定。我相信这样做只会增加应用程序中出现问题的可能性(有状态服务、必须确保初始化操作完成、进行更多服务调用).我以前在不干燥的情况下遇到过问题,我真的不想在每次操作合同和每次呼叫中都添加此额外参数。我将主要自己维护这段代码,并创建使用它的客户机。谢谢你的意见。我认为这是正确的方法,但我会给你另一个答案。我会试试这个,看起来不错。我会叫另一个计划B:)我正在考虑你在编辑中说的话。我可以将其设置为一个参数,因为一旦我设置了其他消费者,它会更容易。我在想一个办法来解决这个问题。我想可以将其设置为字段并将其添加到Channel.Method(clientId,otherParams)中。有没有什么方法可以让Genralize方法在这里有所帮助?@IngóVals因为ClientBase都是生成的代码,所以不容易更改。它是作为分部类生成的,因此您可以对其进行扩展,并定义一个替代构造函数,该构造函数将为您设置客户机参数。或者您可以像我上面所做的那样从ClientBase类扩展到您自己的版本。问题是,因为生成的代码是调用Channel.Method(clientId,otherParams)
的地方,您如何更改它来封装clientId?您需要编写另一组没有client id参数的服务操作,然后从某处检索它并调用底层操作。我尽可能避免自动生成的代码,因此我编写了自己的客户端实现ClientBase的代码。但我现在明白你的意思了。