Best way to support "application/x-www-form-urlencoded" post data with WCF? - wcf

I'm building a WCF service based on a W3C specification which defines a RESTful web service endpoint that accepts "application/x-www-form-urlencoded" post data. WCF doesn't support this type of message encoding by default and I have found a number of different examples of creating a contract that looks like this:
XElement Query_Post(Stream postData);
And then within the implementation decoding the postData stream using the HttpUtility.ParseQueryString method.
Does anyone know of a more strongly typed way of supporting "application/x-www-form-urlencoded" in WCF?
I would like my operation contract to be:
XElement Query_Post(string query, string [] params);

The best way is to use Stream like Raw HTTP POST with WCF or what you are saying.
The reason is because WCF abstracts all the communication-level physical layout stuff out from the service code. Ideally, you would want to make a service that could turn into SOAP or REST just by flipping the switch.
To support it natively, you probably have to extend WebHttpBinding or make your own binding and implement custom encoder. This is symmetric to the output like the linked post says. You have to twist its arms to get WCF to output non-XML/JSON stuff.

The WCF REST Contrib library enables this functionality:
https://github.com/mikeobrien/WcfRestContrib
It includes a POX formatter and form url encoded formatter and allows you to easily create your own. Formatters are mapped to mime types and automatically selected to serialize/deserialize the entity body based on the content type and accept headers.

Related

Implementing versioning a RESTful API with WCF or ASP.Net Web Api

Assume i've read a lot about versioning a restful api, and I decided to not version the the service through the uri, but using mediatypes (format and schema in the request accept header):
What would be the best way to implement a wcf service or a web api service to serve requests defining the requested resource in the uri, the format (eg. application/json) and the schema/version (eg player-v2) in the accept header?
WCF allows me to route based on the uri, but not based on headers. So I cannot route properly.
Web Api allows me to define custom mediatypeformatters, routing for the requested format, but not the schema (eg. return type PlayerV1 or PlayerV2).
I would like to implement a service(either with WCF or Web Api) which, for this request (Pseudo code):
api.myservice.com/players/123 Accept format=application/json; schema=player-v1
returns a PlayerV1 entity, in json format
and for this request:
api.myservice.com/players/123 Accept format=application/json; schema=player-v2
returns a PlayerV2 entity, in json format.
Any tips on how to implement this?
EDIT: To clarify why I want to use content negotiation to deal with versions, see here: REST API Design: Put the “Type” in “Content-Type”.
What you are bringing here does not look to me as versioning but it is is more of content negotiation. Accept header expresses wishes of the client on the format of the resource. Server should grant the wishes or return 406. So if we need more of a concept of Contract (although Web API unline RPC does not define one) then using resource is more solid.
The best practices for versioning have yet to be discussed fully but most REST enthusiast believe using the version in the URL is the way to go (e.g. http://server/api/1.0.3/...). This also makes more sense to me since in your approach using content negotiation server has to keep backward compatibility and I can only imagine the code at the server will get more and more complex. With using URL approach, you can make a clean break: old clients can happily use previous while new clients can enjoy the benefits of new API.
UPDATE
OK, now the question has changed to "Implementing content-negotiation in a RESTful AP".
Type 1: Controller-oblivious
Basically, if content negotiation involves only the format of the resource, implementing or using the right media type formatter is enough. For example, if content negotiation involves returning JSON or XML. In these cases, controller is oblivious to content negotiations.
Type 2: Controller-aware
Controller needs to be aware of the request negotiation. In this case, parameters from the request needs to be extracted from the request and passed in as parameter. For example, let's imagine this action on a controller:
public Player Get(string schemaVersion)
{
...
}
In this case, I would use classic MVC style value providers (See Brad Wilson's post on ValueProviders - this is on MVC but Web API's value provider looks similar):
public Player Get([ValueProvider(typeof(RequestHeadersSchemaValueProviderFactory))]string schemaVersion)
{
...
}

WCF service authentication method

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.

Can I use Json serialization in WCF service?

I am going develop a WPF windows based application. I want to work with Entity Framework Self Tracking Entities and WCF. I was wondering if using Json is possible/recommended? If yes, please assist me; is there any tutorial that can help?
You can use the DataContractJsonSerializer to serialize the messages. You will have to use a REST based service (WebHttpBinding) as SOAP mandates XML as the message payload.
You can tell WCF to use the DatcontractJsonSerializer on the service side by settings in the WebGet and WebInvoke attributes but on the client side you will have to manually use this serializer as REST doesn;t have a metadata standard and therefore you have to create the requests and manage responses in a more manual fashion
Here is a reasonable guide to using Json and REST support in WCF
However, what is your driver to using Json? WCF is much more geared to SOAP based interaction currently (although the WCF 4.5 WebApi is going to address that to quite a degree). As your client is WPF you don't seem to gain alot from using Json

Is it possible to implement a redirector / reverse proxy using RequestInterceptor from WCF REST Starter kit

I am attempting to implement a reverse proxy using the RequestInterceptor from WCF REST starter kit. I am able to set the basic header properties and configure the calls. I am getting stuck with the following aspects:
Returning an appropriate response - my webservice can return text+xml, image or json. I am not able to send the appropriate response type. The Message.CreateMessage overloads are all SOAP aligned i.e. they accept only Xml constructs, so I am not able to send either JSON or image streams. I need to convert them into XElements - I am definitely doing something wrong here.
I also want the reverse proxy to be functioning well in the presence of cookies, gzip/deflate and SSL.
Based on the above requirements, do you think it makes sense to do this using REST starter kit? The Requestinterceptor was fairly easy to plug into, however the rest of the code is driving me nuts.
There is a mapping between both JSON and arbitrary binary content to XML which is used in messages for WCF (see some examples at http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx), so you can use Message.CreateMessage to create non-XML messages as well.
Having said that, it's really not intuitive to do that in WCF as of now. The new libraries in the WCF Web API - http://wcf.codeplex.com - provide a very nice way of intercepting / redirecting / bypassing the WCF pipeline especifically for HTTP messages. Also, it support multiple formats in a native way (i.e., without need to do some mapping to XML).

How to change Wcf to use a different serializer?

By default WCF use DataContractSerialization so if we can change it then my question is how to change it and when should we need which serialization on wcf ?
You can use the XmlSerializerFormatAttribute attribute on your service contract to force WCF to use the XmlSerializer.
WCF has a nice feature that a method can return Message or a Stream (see Returning raw json (string) in wcf and How to set Json.Net as the default serializer for WCF REST service as examples). The corresponding code which you need to write can be more easy as if you will use more advance techniques Extending Encoders and Serializers. So it is very easy to implement Streaming Message Transfer for example or just returning JPG or Excel file as a result of some WCF method.
The default choice of DataContractSerializer is good for most purpose. You can also use the DataContractJsonSerializer specially for REST type services and if the client expects Json content type. The other option is XmlSerializer for interoperability purpose if you need more control over the generated XML. DataContractSerializer is more efficient than XmlSerializer.
In 3rd party options you can use protobuf-net from Google which is more efficient than DataContract Serializer.