我只是深入了解它并发现了新的细节。
不是'UriTemplate'一般会导致第二次调用'AfterReceiveRequest',而是在!
中的可选参数如果我通过
调用方法http:/ / myserver / result / val1
AfterReceiveRequest将被调用两次。
如果我传递了所有可能的参数,例如
http:/ / myserver / result / val1 / val2 / val3
没有无用的调用。这种行为是否符合预期?
UriTemplate = "result/{para1=null}/{para2=null}/{para3=null}"
---在首发后,仅供参考---
在实施WCF REST服务系统时,我遇到了http-headers的问题。
在ServiceContract
我的UriTemplate
属性中有一个WebGet
定义的方法,因此可以通过
http://server/resource/val1/val2 ...
而不是
http://server/resource?para1=val1¶2=val2 ...
(由于兼容性原因,我需要这个。)
http-headers 集合中还有一个重要的值,我需要阅读。因此,我实施IDispatchMessageInspector
并将此检查器添加到EndpointDispatchers
MessageInspectors
集合中。由此,WCF将调用AfterReceiveRequest
,我可以访问WebOperationContext.Current.IncomingRequest.Headers
以读取所需的值。
UriTemplate
- 映射,但是没有将头条目从原始调用传递给生成第二个电话。因此,AfterReceiveRequest
(当然还有BeforeSendReply
)将被调用两次,但来自真实客户端调用的标头值仅包含在第一次调用中。
此外,我发现没有办法关联第一个和第二个AfterReceiveRequest
调用,以实现一个“特殊方式”,用于将标头值从第一个调用传递到第二个调用。
有没有办法告诉WCF将标题路由到UriTemplate
- 重定向的第二个电话?
以下是一些明确的代码片段:
[ServiceContract]
public interface IMyService
{
[WebGet(UriTemplate = "result/{para1=null}/{para2=null}/{para3=null}")]
bool MyMethod(string para1, string para2, string para3);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
[MyServiceInspectorBeavior]
public class MyService : IMyService
{
public bool MyMethod(string para1, string para2, string para3)
{
return DoTheWork();
}
//...
}
public class MyServiceInspectorBeavior : Attribute, IServiceBehavior
{
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (EndpointDispatcher epDispatcher in serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>().SelectMany(cDispatcher => cDispatcher.Endpoints))
{
epDispatcher.DispatchRuntime.MessageInspectors.Add(new MyInspector());
}
}
//...
}
public class MyInspector : IDispatchMessageInspector
{
//this is invoked twice for each client request,
//but only at the first call the header is present...
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
WebHeaderCollection webOpContext =
WebOperationContext.Current.IncomingRequest.Headers;
string xForwardedIp = webOpContext["X-FORWARDED-IP"];
WriteLog(xForwardedIp);
return OperationContext.Current.IncomingMessageProperties["ActivityId"];
}
//...
}