我正在WCF中做一个消息检查器:
public class LogMessageInspector :
IDispatchMessageInspector, IClientMessageInspector
Run Code Online (Sandbox Code Playgroud)
实现方法:
public object AfterReceiveRequest(ref Message request,
IClientChannel channel, InstanceContext instanceContext)
Run Code Online (Sandbox Code Playgroud)
我可以使用以下命令获取调用服务的名称:
instanceContext.GetServiceInstance().GetType().Name
Run Code Online (Sandbox Code Playgroud)
但是如何获取调用操作的名称?
我实现IDispatchMessageInspector.AfterReciveRequest然后我这样配置:
<configuration>
<system.serviceModel>
<services>
<service
name="Microsoft.WCF.Documentation.SampleService"
behaviorConfiguration="inspectorBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/SampleService" />
</baseAddresses>
</host>
<endpoint
address=""
binding="wsHttpBinding"
contract="Microsoft.WCF.Documentation.ISampleService"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="inspectorBehavior">
<serviceInspectors />
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add
name="serviceInspectors"
type="Microsoft.WCF.Documentation.InspectorInserter, HostApplication, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
</configuration>
Run Code Online (Sandbox Code Playgroud)
但它不起作用.
我检查我的程序集和我的本地参考,我没有找到Microsoft.WCF.Documentation.InspectorInserter或HostApplication我在网上搜索下载HostApplicationDLL但我什么也没找到.
我需要做什么?
我需要实现更多的东西,或者我只需要这个配置.
我试图在WCF服务实现中使用IDispatchMessageInspector来访问自定义标头值.
就像是:
public class MyService : IMyService
{
public List<string> GetNames()
{
var headerInspector = new CustomHeaderInspector();
// Where do request & client channel come from?
var values = headerInspector.AfterReceiveRequest(ref request, clientChannel, OperationContext.Current.InstanceContext);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经实现了自己的IDispatchMessageInspector类.
public class CustomHeaderInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
var userName = prop.Headers["Username"];
return userName;
}
}
Run Code Online (Sandbox Code Playgroud)
我怎么通过
System.ServiceModel.Channels.消息和
System.ServiceModel.IClientChannel
到AfterReceiveRequest叫服务实现?
编辑:
很多像这样或者 …
我刚刚开始拦截对我的WCF服务的请求.
我正在使用看起来像这样的Java代码调用Web服务(简短版本)
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Username", "Testname");
Run Code Online (Sandbox Code Playgroud)
我收到了请求,但我无法在邮件请求中找到/找到标头.我尝试过这样的事情:
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
int headerIndex = request.Headers.FindHeader("Username", string.Empty);
var username = request.Headers["Username"]
return null;
}
Run Code Online (Sandbox Code Playgroud)
但我总是以-1或异常结束.这样做的正确方法是什么?我在Java方面做错了吗?
我在这里有两个问题: -
1)两者之间的基本区别是什么 Microsoft.ServiceModel.Web.RequestInterceptor and System.ServiceModel.Dispatcher.DispatchRuntime.MessageInspectors (IdispatchMessageInterceptor)
两者似乎都是请求/消息拦截器,可用于在请求管道中实现自定义验证/拦截器.
什么时候使用另一个?
2)亦如何插件RequestInterceptor在RouteTable.Routes.Add(new ServiceRoute())
我有这样的课 -
public class AuthenticationInterceptor : RequestInterceptor
{
//Authentication logic goes here......
}
Run Code Online (Sandbox Code Playgroud)
和这样的路线定义: -
RouteTable.Routes.Add(new ServiceRoute(routePrefix, new MyServiceHostFactory(container, (sh) => {
foreach (System.ServiceModel.Dispatcher.ChannelDispatcher cd in sh.ChannelDispatchers)
{
foreach (System.ServiceModel.Dispatcher.EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.MessageInspectors.Add(new AuthenticationInterceptor());
}
}
return sh; })));
Run Code Online (Sandbox Code Playgroud)
这是以下定义MyServiceHostFactory: -
public MyServiceHostFactory(IocContainer container, Func<ServiceHost, ServiceHost> createservicehost = null);
Run Code Online (Sandbox Code Playgroud)
现在它抛出以下错误: -
The best overloaded method match for 'System.Collections.Generic.SynchronizedCollection<System.ServiceModel.Dispatcher.IDispatchMessageInspector>.Add(System.ServiceModel.Dispatcher.IDispatchMessageInspector)' has some invalid arguments …
我创建了一个自定义soap标头,并通过IClientMessageInspector将其添加到我的消息中
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
var header = new MessageHeader<AuthHeader>();
header.Content = new AuthHeader(Key);
header.Actor = "Anyone";
var header2 = header.GetUntypedHeader("Auth", "xWow");
request.Headers.Add(header2);
return null;
}
[DataContract(Name="Auth")]
public class AuthHeader
{
public AuthHeader(string key)
{
this.Key = key;
}
[DataMember]
public string Key { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我还有一个IDispatchMessageInspector,我可以在列表中找到正确的标题.但是,没有任何价值.我知道值正确地穿过了电线,因为消息字符串是正确的
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Auth s:actor="Anyone" xmlns="xWow" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Key xmlns="http://schemas.datacontract.org/2004/07/xWow.Lib">HERE IS MY KEY VALUE!!!!</Key>
</Auth>
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://localhost:26443/AuthService.svc</To>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IAuthService/GetPayload</Action>
</s:Header>
<s:Body>
<GetPayload xmlns="http://tempuri.org/"/>
</s:Body>
</s:Envelope>
Run Code Online (Sandbox Code Playgroud)
但似乎没有任何属性可以检索此值.MessageHeaderInfo类有Actor等,但我找不到其他任何有用的东西. …
我有一个关于在MessageInspector和Web服务之间共享信息的问题.
我有一个标识符(Guid),用于"绑定"AfterReceiveRequest和BeforeSendReply.它工作正常.但我希望这个标识符也可以在Web服务中使用的方法中使用.这对于跟踪日志中的问题非常有用.
下面是一个小例子来说明这个想法.我的问题是找到一个解决方案,可以从方法AfterReceiveRequest访问返回对象.与"MagicStuff"一致.
namespace Demo.MessageInspector
{
public class DemoMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
Guid activityId = Guid.NewGuid();
MyLog.Message("AfterReceiveRequest", activityId);
return activityId;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
Guid activityId = (Guid)correlationState;
MyLog.Message("BeforeSendReply", activityId);
}
}
}
namespace Demo.WebServices
{
[ServiceBehavior]
[MessageInterceptionServiceBehaviour]
public class MyWebService : IMyWebService
{
public void MyWebServiceMethod()
{
Guid activityId = (Guid)MagicStuff; // <-- correlationState from AfterReceiveRequest
bool success = DoSomthing();
if (!success)
MyLog.Message("Error happened …Run Code Online (Sandbox Code Playgroud) 我有一个WCF服务,返回给客户端的JSON.
这是app.config
<system.serviceModel>
<services>
<service name="MyServices.MyService">
<endpoint address="" behaviorConfiguration="JsonBehavior" binding="webHttpBinding"
contract="Myervices.IMyervice">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/MyEmulator/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="JsonBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
Run Code Online (Sandbox Code Playgroud)
这是服务公开的示例操作
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, Method = "GET", UriTemplate = "me/{id}")]
JsonObject GetObject(string id, string connection_type);
Run Code Online (Sandbox Code Playgroud)
现在,我想记录服务从客户端收到的每个请求以及正在发送回客户端的响应......在这种情况下,它会犯罪JSOn.
我创建了一个自定义MessageInspector,如下所示
public class MyMessageInspector : IDispatchMessageInspector
{
private bool LoggingEnabled;
#region IDispatchMessageInspector …Run Code Online (Sandbox Code Playgroud) 我正在尝试关注此博客文章:http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx
我的目标是以某种方式获取传入请求的远程地址,但由于某种原因,地址要么在任何参数中都无法看到,要么为空.
这是我正在实现的界面:
public interface IDispatchMessageInspector
{
object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext);
void BeforeSendReply(ref Message reply, object correlationState);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试获取远程地址的方法是AfterReceiveRequest.我检查了两个参数request和channel.此外,它似乎应该channel.RemoteAddress是它应该是,但由于某种原因该属性为空.该request参数也为null,但我猜这是因为我正在进行GET而不是POST.
下面是我正在调用以测试它的方法的签名.
[OperationContract, WebGet( UriTemplate = "{*path}", ResponseFormat = WebMessageFormat.Json)]
string[] GetList(string path);
Run Code Online (Sandbox Code Playgroud) 我正在尝试记录来自 WCF 服务的请求和响应。到目前为止我所做的是:
public class OutputMessageInspector : IDispatchMessageInspector
{
int lastLogId;
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
// Parse request & read required information
// Insert request data into log tables
// Set lastLogId to the id created above
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
// Parse reply
// Using lastLogId update the response column in database table
}
}
Run Code Online (Sandbox Code Playgroud)
一切正常,但我有一个担忧:
AfterReceiveRequest并且BeforeSendReply必须同步工作,以便BeforeSendReply更新正确的记录。我想到的情况是服务同时从多个客户端调用,问题:
lastLogId在多个请求和响应之间混乱和混乱吗?BeforeSendReply可以在多个客户端同时调用服务的情况下正常工作?如果是,请给我一个解释,以确保我的想法;如果否,请提供更好的解决方案。