Applying [WebInvoke(ResponseFormat = WebMessageFormat.Json)] in config file - wcf

I'm writing what I'm referring to as a POJ (Plain Old JSON) WCF web service - one that takes and emits standard JSON with none of the crap that ASP.NET Ajax likes to add to it.
It seems that there are three steps to accomplish this:
Change "enableWebScript" to "webHttp" in the endpoint's tag
Decorate the method with [WebInvoke(ResponseFormat = WebMessageFormat.Json)]
Add an incantation of [AspNetCompatibilityRequirements(RequirementsMode
= AspNetCompatibilityRequirementsMode.Allowed)] to the service contract
This is all working OK for me - I can pass in and am being returned nice plain JSON.
If I remove the WebInvoke attribute, then I get XML returned instead, so it is certainly doing what it is supposed to do. But it strikes me as odd that the option to specify JSON output appears here and not in the configuration file. Say I wanted to expose my method as an XML endpoint too - how would I do this? Currently the only way I can see would be to have a second method that does exactly the same thing but does not have WebMethodFormat.Json specified. Then rinse and repeat for every method in my service? Yuck.
Specifying that the output should be serialized to JSON in the attribute seems to be completely contrary to the philosophy of WCF, where the service is implemented is a transport and encoding agnostic manner, leaving the nasty details of how the data will be moved around to the configuration file.
Is there a better way of doing what I want to do? Or are we stuck with this awkward attribute? Or do I not understand WCF deeply enough?

I haven't fully tested this out yet, BUT, I took a look at WebMessageFormat in reflector and where it was used in code.
There is a attribute of the webHttp element called defaultOutgoingResponseFormat that can be set to "Json" or "Xml".
<behaviors>
<endpointBehaviors>
<behavior name="ServicesJSONEndpointBehavior">
<webHttp defaultOutgoingResponseFormat="Json"/>
</behavior>
</behaviors>
I've run into the same issue and typically crufted work-arounds after searching online without much info.
I'll give it a shot with multiple configured endpointBehaviors and report back.
UPDATE 6/5/2011
FYI -- I've ditched vanilla WCF with all its hair-pulling scenarios like this that should be simple, in favor of ServiceStack ( http://servicestack.net/ ). If you're looking to put together a standard REST style / document-oriented service over HTTP that out-of-the-box supports JSON / XML / CSV (and in the future protocol buffers) and that allows you to put together clean MVC-style routes with ease, give ServiceStack a hard look. There are a number of things that ServiceStack will handle rather easily and cleanly that always turn out to be a major PITA due to some wonky configuration issue or similar in standard WCF. ServiceStack uses it's own JSON serializer, which as an added bonus, outperforms DataContractJsonSerializer and JSON.NET as Demis mentions below.

Related

Best to consume WS operations in Mulesoft

New to Mulesoft and have a question regarding SOAP consumer for calling Web service.
Suppose there is a web service with a few operations. As an example the WS has operations for “createUser”, “validateUser”, “isAccountActive” and etc.
Let say “createUser” requires me to pass “userName”, “firstName”, “lastName”, “address”, “city”, “zipCode” and etc
While “validateUser” only requires “userName” only and “isAccountActive” requires “username” and “zipCode”
Suppose the information is coming as a http post in this format for createUser
<Service>
<operation>CreateUser</operation>
<userName>jdow123</userName>
<firstName>John</firstName>
<lastName>Dow</lastName>
<address>123 East street</address>
<city>NY</city>
<zipCode>123456</zipCode>
</Service>
And like this for isAccountActive
<Service>
<operation> isAccountActive </operation>
<userName>jdow123</userName>
<zipCode>123456</zipCode>
</Service>
So in this case does it make sense to create multiple subflows like the digram I have to handle each operation or there are better ways
Thanks
I would still use a sub-flow for each operation. One, it will allow reuse later and avoid duplicating code. It will allow you to test each operation individually and allow you to easily mock each sub-flow as part of a larger test - increasing testability.
As for the mapping to each sub-flow, you are currently using a choice router - It depends on you interface for that flow. If it’s a rest api you could use APIKit in Mule to map requests to a specific flow for create vs validate for example. But it all depends on your requirements.

How to remove xmlns:xsd, xmlns:xsi, xsi:type from the WCF output using XMLSerializer

Using WCF Restful service with XmlSerializer I get the below response.
<?xml version="1.0" encoding="utf-8"?>
<availabilityResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xyz.com/ABCService">
<availabilityResult>
<title xsi:type="Availability_1">
<titleId>0010327457</titleId>
<availability>
<purchasable>false</purchasable>
<availableCopies>0</availableCopies>
<totalCopies>0</totalCopies>
</availability>
</title>
</availabilityResult>
</availabilityResponse>
(I wish to remove xmlns:xsd, xmlns:xsi and xsi:type tags)
"Availability_1" is one my derived type i used in my code. I really do not want to show this in the response.
I am using XmlSerialzer by specifying [XmlSerializerFormat] at the service contract.
WCF is able to serialize my response properly but the only issue i have is with the extra xmlns tags. Yes, I know they are useful stuff there. But, the client is interested only in the plain xml.
By looking at various posts in stackoverflow i understood i could do this by overriding few of the methods of XmlTextWriter. But the problem I have is how to let the WCF know to use my customXmlWriter (inherited from XmlTextWriter) instead of generic XmlTextWriter while serialization.
How to pass my customXmlTextWriter to the XmlSerializer which i do not have any control at this point.
I just created my data classes and defined the service contract methods from my end but did not have to do any of the serialization stuff from my side as the WCF takes care of it on its own.
A slightly different idea, but it's in the line of separation of concerns, as writing custom serialisers to actually make the responses sort of "invalid" seen from a true compliancy principe can be seen as an anti-pattern.
My idea is to develop your own IIS custom HTTP handlers and add it to the IIS processing pipeline. Doing so, will allow you to expose both the tweaked responses and the fully compliant ones.
The custom HTTP handler could use a simple XSLT to remove the required namespaces.
Have a look at this article to get started - http://www.iis.net/learn/develop/runtime-extensibility/developing-iis-modules-and-handlers-with-the-net-framework

Sending licensekey from client to server via WCF in header

I want to authenticate app server against my central with license key and I do not want to include it as a parameter in my calls.
I have implemented custom ServiceAuthorizationManager but I am not sure what is the best way and place to set this licenseKey on client side.
I tried below (I might be completely wrong with approach)
<endpoint address="http://127.0.0.1:8000/ApiDataService" binding="wsHttpBinding"
contract="MyInterfaces.IApiDataService">
<headers>
<LicenseKey>MyLicenseKey</LicenseKey>
</headers>
</endpoint>
then in ServiceAuthorizationManager.CheckAccessCore(OperationContext operationContext)
I have managed to find a header's index via:
operationContext.RequestContext.RequestMessage.Headers.FindHeader("LicenseKey", "")
but retrieved HeaderInfo does not have my content any more.
I am sure it is in operationContext.RequestContext so I should be able to capture it somehow.
Any idead how?
Is there any nicer/standard way of doing this?
Should I use <identity\> element?
I am more than happy to use operationContext.ServiceSecurityContext but I do not know how to set it up on client side and where to place my custom license key.
I have multiple endpoints so I would prefer to have a single place for my license key. Setting it from code would be even better.
Thanks
This article here Globalization Patterns in WCF (WS-I18N implementation) may be of interest to you as it demonstrate how to use WCF out-of-band mechanisms to send and receive custom information. It's about globalization, not licensing of course, but the problem seems somewhat similar.

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.

Exposing only the interface in WSDL in WCF, rather then the service

I have a service contract ICalc, and I want to expose a WSDL through the MEX endpoint, which will only describe the ICalc contract, i.e. will contain only the portType element, without the service element.
Is there a way to do that in WCF?
It sounds like what you want is to expose an abstract WSDL instead of a concrete WSDL. As far as I know, there is no built-in way in WCF to accomplish this.
One thing I thought about is that it may be possible to accomplish this by manually removing the <service> and <binding> elements from the generated WSDL file in a custom IWsdlExportExtension extension. However, I was unable to get it to work after a few tests (if I removed the service, WCF would just show the HTML help screen when the WSDL was requested).
There might be a way to get it though, so maybe give it a try.