How does ILogger deserialize WCF Messages? - wcf

I have a IClientMessageInspector with a BeforeSendRequest and AfterReplyRequest. There are credentials in the body I want to strip out before logging (bad API design, I know, but not my API).
Anyways... I'm doing the whole CreateBufferedCopy/create two copy thing (one for logging, one to put back in the ref'd parameter). I'm doing so because once you do GetReaderAtBodyContents the Message is unusable. And all of this works.
But something is bugging me...
If I don't do any of the CreateBufferedcopy stuff, and just use ILogger to LogTrace the message as-is, it can do so but the message is still usable.
Anybody know how is it that ILogger is able to deserialize a Message's without leaving it unusable? Is ILogger somehow drilling down to the message's _operationFormatter?

Thanks to those who commented. I'm using .NET Core 6, although the having to implement a CreateBufferedCopy thing does not appear to be .NET Core specific (from what I've been able to read in the docs so far).
Using ILogger itself isn't a problem that I'm trying to be address. The same issue would happen if I were using Console.WriteLine.
From digging around in the debugger, it looks like getting to the Formatter is "firewalled" via Internal scoped functions and System.Private.ServiceModel.
I think the answer here is that Microsoft really, really doesn't want to let you look at a reply/response without copying it first (and then re-copying it before continuing).

Related

NServiceBus Endpoint Routing Injection

I am trying to inject my own IRouteMessagesToEndpoints in NServiceBus with structure map as I need to redirect various messages to different endpoints depending on some business logic (not via namespace/assembly/type). This would allow it to fire using bus.Send(); and be configured to our requirements. I thought this was possible, but I can't seem to get it to work. I have tried using the Configure.Component() and ObjectFactory.Configure() for the injection, and both run without any exception, but when I debug my implementation of the interface the breakpoint does not hit.
My question is, can it be done this way (there's nothing on the internet that covers this)? I notice that the EndPointRouter in the GatewayReceiver has a setter, but I cannot work out how to access the property.
Unfortunately, even though IRouteMessagesToEndpoints is a public interface at the moment is not possible to replace the default implementation, sorry!
Please raise an issue about it in https://github.com/Particular/NServiceBus.Gateway/issues/new so we can discuss it better.

Generic WCF Routing/Forwarding/Proxy Server

Is it possible to create a "generic" as in "adaptable" routing service, which will NOT have any public methods to call. Instead, you'd be able to call any command, which would then be mapped in the service and will pass it to appropriate end point with simple message transformation where required.
It may be hard to understand and idea might seem a bit crazy (it came from a colleague of mine), but it's clearer if you look at the example:
similar to what's described in this article, only difference is that our service should not have a "SubmitTimeSheet" public method, in fact it should have no public methods to call. We'd have to "intercept" an incoming call on a much lower level before it returns "Method Not Found" error.
Is this at all possible? The reason for this is obvious: possibility of adding new clients without having to change the code. All we'd have to do is to add a new mapping entry in some sort of config file or even database, e.g.
<Client address="newClientAddress" method="DoAnything" transformation="NewClientDoAnything.xslt" endPoint="endPointClientAddress" endPointMethod="endPointClientDoAnything" />
Check out WCF 4 routing - supports content based routing, xpath transforms and much more.
http://blogs.msdn.com/b/routingrules/
They have already done it in Nirvana. But it is very expensive.
This is not possible in WCF unless you define your contract as a very loose, fit-for-all contract which takes a message and returns a message. By doing this, you will los all the goodness (although not huge goodness in WCF) of WCF.

Accessing the ServiceModel layer directly

I'm new to WCF, so apologies if I'm missing the boat completely.
It seems like WCF provides plenty of functionality for using the "Channel" layer by itself. For example, to create a server, you can create a channel listener from a binding and call WaitForRequest, Reply, etc. These methods all deal with Message objects, so it is up to you to do something with the message.
My question has to do with what happens once we've already got a message. Suppose I have an object that implements a service, described by a ServiceContract, and a Message object which I know represents a call to a particular operation. What I'd really like to do is something like:
Message requestMessage = GetMessageSomehow();
OperationDescription oc = GetContractForMessage();
Message replyMessage = Invoke(myService, oc, requestMessage);
At the very least, if I could somehow access the IOperationInvoker and IDispatchMessageFormatter objects that get created for a type, it would be pretty simple to chain them together to get the functionality I'm looking for.
In my particular case, I need to implement some simple Soap 1.1 and 1.2 services (with no WS-Addressing). I already have HttpListenerRequest/Response objects, and can route based off of either the SOAPAction or ContentType header.
I think having this functionality would also be pretty useful for unit testing. For example, I need to implement to existing clients. It would be nice to have unit tests where I could test that the Attributes on the service class are correct (i.e. that the message that I know I will be getting gets properly translated into a call on my service interface).
Any suggestions?
Serialization/Deserialization from that Message instance to actual parameters for a call is usually done by an IDispatchMessageFormatter / IClientMessageFormatter.
On the server side, an IDispatchMessageFormatter is injected into the DispatchRuntime by a custom operation behavior that the data contract serializer (or other serializer) inserts.
But... if you're not using ServiceHost, there's no DispatchRuntime. Basically, if you want all of this, you're going to have to do all the hard work yourself :)
That said, if you can get an OperationDescription object, you should be able to instantiate a DataContractSerializerOperationBehavior, but you won't be able to get an IDispatchMessageFormatter out of it... you can get an XmlObjectSerializer, though, which might, or might not, be useful for you.
Notice that an IOperationInvoker wouldn't help all that much, since that presumes you've already done message serialization/deserialization, so it's not really all that useful (and the rest of the functionality is fairly simple for basic use cases if you want to roll it yourself)

Occasional error on production server: Method <name> is not supported on this proxy

One of 4 production servers once in a while generates tons of error claiming:
Method RunRules is not supported on this proxy, this can happen if the method is not marked with OperationContractAttribute or if the interface type is not marked with ServiceContractAttribute.
The method "RunRules" is one of the methods in wcf [ServiceContract] interface, and it is marked as [OperationContract].
Before this error, in the same method, occasionally it would get a wrong service through castle container. After I put more logging information to nail down exact cause, it mutated into the current error.
It is a webservice the error comes out of, it tries to call into a windows service through wcf endpoint when this happens. And this only happens on one specific machine. The frequency is about once a week or 2 weeks. Once recycle of the webservice happens (3 hours), the error stops.
To me it is almost like corrupted vtable. Just wondering, how would you approach this problem? Hate to ask IT people start to re-image the machine without solid proof.
Thanks!
No simple answer for such abstract magic error, so try out logging entire call stack, especially internal Castle DLL calls, if standart exception does not contain such deep call stack information - use reflection.
// use this in loop incrementing levelIndex up to st.FrameCount
// to grab all possible callstack entries
StackTrace st = new StackTrace();
st.GetFrame(levelIndex).GetMethod().Name;
Then using utility like ILSpy disassemble Castle DLL and try out analyze which state causes concrete execution flow which ends up with exception you got.
If you able log callstack - please share so I would be able check it as well.

How do I follow a WCF request from start to finish?

I have a WCF service defined, it accepts JSON and maps that JSON to an object at which point I can then begin debugging code.
Sometimes, the object fails to create. Most recently my service had a BodyStyle of Wrapped but should have been Bare. In this case I would have liked to watch the request come in and see what happens to it as it gets mapped from JSON to POCO and then onto the service so I can watch for errors.
I'd also like to see what happends with the response where I have also had issues in the past.
What is the best way of seeing what is going on in WCF when it is (kind of) out of my control? What kind of logging/tracing can I use and can I see errors/exceptions being thrown by WCF?
Thanks
Scott
I don't know much but svctraceviewer might help in case you haven't heard about it already.
Arnis gives a good suggestion. I'd also suggest using Fiddler to trace WCF traffic assuming you are using a HTTP end point. I've used fiddler to troubleshoot WCF issues so it might be helpful to you as well.