I'm not sure the title really gets across what I need to do. I want to force or coerce or whatever a WCF service to accept a slightly different SOAP message. Here is what the service expects:
<sch:modifyCandidateNotification>
<!--Optional:-->
<sch:request vueCandidateID="?" clientCandidateID="?" clientCode="?">
...
but here is what I want to send to the service:
<sch:modifyCandidateNotification vueCandidateID="?" clientCandidateID="?" clientCode="?">
I'm not responsible for sending the SOAP, one of our partners is and they can't alter what they are sending. I don't want the structure at all.
I've tried adding [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare)] to the interface, but to no avail. Also, I'm using a basicHttpBinding. I've tried with the wsHttpBinding and did not see any difference.
Thanks.
Related
I'm building a WCF SOAP service at the moment. I will, of course, need some authentication on the service.
Reading this very helpful blog post says that to use the built-in authentication points requires that the endpoint use the wsHttp binding.
This would be fine if I could guarantee that users would be communicating with the service through a client based on the meta-data exposed by WCF (basically, something like a client written in C# with a web service reference). However, I can't guarantee this!
I will still need to allow users to communicate with just raw (unencrypted) XML.
So, questions:
Does the wsHttp binding still allow for raw XML input?
If not, would I be wiser to
Implement two separate authetication points? One for raw XML input and one for encrypted input
Or
Allow input from wsHttp to fall back on some in-method validation that would be shared with the raw XML input?
Is it wise to allow users to pass their credentials inside a raw XML request?
EDIT: It sounds like I miscommunicated or misunderstood something in my original post, so here I will clarify what I mean by "raw XML".
By raw XML, I mean just the SOAP packet and the accompanying HTTP headers - as I might send from soapUI or Fiddler. As I understand it, messages over the wsHttp binding are encrypted when a client is generated from the WSDL (for example, in C#).
If this is not the case, then how would I go about attaching the same sorts of credentials to a raw XML (for want of a better term) request as I do a request run through a client? Are they attached as HTTP headers? XML elements in the SOAP envelope?
wsHttp is a SOAP binding, which means that your content gets wrapped in a SOAP envelope, possibly with headers relating to the message and various WS-* specifications being used.
I would ask why you need to support raw XML? Most platforms today support SOAP messaging and the whole idea of SOAP is to provide interoperability between different platforms. On most platforms it is as easy to develop a SOAP client as a raw XML client. In most cases, it is simply a case of taking the WSDL and generating a client. If you want to use standard facilities like authentication and message encryption then this is a much better way to go.
There are currently no hooks to do interoperable authentication for raw XML. You will have to come up with your own mechanism to do this and it will be non-standard. For your web service users, this means it will be probably entail more development effort than if you just went with SOAP.
I'm building a WCF SOAP application. The WSDL file has numerous operations of which many have the same argument type. The WSDL file defines all soapAction attributes as "''". When I try to start such a service WCF throw an exception saying that soapActions have to be unique.
After some googling I'm even more puzzled than before. I used SOAPUI to create a mock service with two operations which take the same input type and without the soapActions defined it always chooses the same operation. When the actions are defined it works fine.
My questions are:
Can you make a WCF SOAP service without unique soapActions (actually leaving the soapActions "''" as defined in the original WSDL)?
How can a service choose the right operation without the soapAction defined?
Edited:
I'm not in control of the WSDL. I'm using the WSCF.Blue tool to create a service stub from the WSDL file. I might be able to modify the WSDL, but I want to see if there is some possibility to leave it as it is.
It is not very clear from your question but I suggest you are building service based on some defined WSDL, aren't you? WCF by default uses SOAP action because it is required part of WS-I Basic Profile 1.1 offered by WCF services with BasicHttpBinding. WSDLs with empty SOAP actions are used when the action is defined by root body element.
WCF samples provides example of custom DispatchOperationSelector which is able to route messages to operations by their root body element. This is probably what you need to add to your service so that clients based on provided WSDL can call it.
I want to add a complex poco that will pass itself within each wcf call. Whats the bast practice for this case?
Typically, the best way to do something like this is passing such "meta-information" in a WCF header. You can easily create a message inspector to extend WCF (it's really not that scary and hard to do!) which would inject the POCO class (or what of it is necessary) into every outgoing request from the client, and retrieve it from the header and validate it on the server side.
There are a number of pretty good blog post out there showing you how to create a message inspector:
Richard Hallgren's WCF postings
Writing a WCF message inspector
Automatic Culture Flowing with WCF by using Custom Behaviour
Check out the two relevant interfaces to implement:
IClientMessageInspector on the client side, which has a BeforeSendRequest and AfterReceiveReply message to implement
IDispatchMessageInspector on the server side, which has a AfterReceiveRequest and BeforeSendReply method to implement
Here you go, check this out...
https://kinnrot.github.io/passing-complex-type-through-wcf/
I have a class, in which I have a service reference (WCF) to an ASMX web service.
This obviously generates local proxy methods such as
string DoSomething(string someParameter, string someOtherParameter)
I have a method that receives a WCF message class already representing a call to this service, which I simply need to forward
I could of course use XmlDictionaryReader to extract the information from the WCF message, deserialise into the proxy classes and pass those into the proxy method, but as these will simply get serialised back it seems very wasteful
How can I call the service using the already serialised message? (I assume I will need to modify the soap action on the incoming message)
There's a two-part series on how to build a WCF router on MSDN - maybe that helps? Seems like that's more or less what you're trying to do - use a WCF service to basically route a message on to a second service (ASMX in your case).
Marc
I am using WCF as a client for a java web service. I have not control over the server side.
In the response I get from the web service there is no xmlns attribute on the first element inside the soap headers. Because of this WCF returns null as the result of web service call.
Apart from the missing xmlns the response is perfect and if I add the xmlns using fiddler then everything works as expected. I don't know enough about SOAP to know if the xmlns attribute is really required.
Is there a way to avoid this problem, either getting WCF to ignore the missing xmlns attribute or even a hook that would allow me to manually munge the response before it gets to WCF?
This appears to be a pretty old question, so I'm not sure if you ever addressed this. If you are working with a WCF client for a Java Axis service, you will find that you will need to get used to using MessageInspectors to override the behavior of the request and response.
Using the AfterReceiveReply method you should be able to copy the original message and alter the headers. Also check out Step 5 from this MSDN article.
You can't alter the response headers directly in this method as far as I can see, because they are read-only, therefore copying and then replacing the reply with a doctored version is the only way I can think of to correct the missing namespace.