This one is for the bloggers among my readers but actually everyone can find it useful.
You might have noticed recently how downloadable items in my blog appear. For example here is my unit tests presentation:
My file storage service is microsoft's Skydrive. Basically you can upload there any file you want and share it with everyone. This is a free service.
Generally I'm happy with it but here are some points to improve:
There is no direct link for download - users need to enter the "windows live" portal and download from there. I guess there is a traffic reason for this. But there may be alternatives, like having the link embedded in the consuming site with some logo/link to msn. Update:Tim Acheson has created an API to get the direct link.
The download link in the live spaces portal is not explicit enough. Yes, the file is just one click away, but the image does not look clickable enough and the "download" link is pale:
No statistics such as "how many users downloaded this file". Very important, in particular to bloggers.
The embedded files do not appear in feed readers (since they use IFrame):
site:
reader:
If you will surf to
before you'll notice it you'll be in
which makes it hard to add skydrive to the browser favorites.
I know some Microsoft employees read my blog so hopefully these issues will be resolved in a future release ;-)
However it is interesting to see how it is still relevant even a few years later when new frameworks are around.
The two common paradigms for building a web service are code-first and contract-first. The former means you start writing your c#/java/whatever service code and generate the contract (wsdl) from it. The latter means you first create the wsdl (either manually or using some tool) and then create the service code from it.
So with code-first you write this:
And this is auto generated for you:
While in contract-first you write the wsdl (possibly using a tool) and the code is generated.
Pros for code-first:
Developers are already familiar with code so development is faster. Being veteran developers, architects are also code-savvy.
More online resources
You'll need to use it anyway
Pros for contract first:
Better interoperability
Defers implementaiton details
You'll need to use it anyway
Code first is the de-facto "default setting" in almost all frameworks - most tutorials and documentation use it. So contract-first is much more interesting from a "let's write an interesting post" POV.
In the next series of posts I'll write on the contract-first approach using several frameworks.
My opinion on the matter is that it does not really matter. Contract-first is important from the interoperability perspective, but most frameworks do not support all wsdl/schema artifacts. So ignoring the code you'll find yourself working with a perfectly interoperable wsdl that no framework can consume. For example xsd:union is not supported in .Net and xsd:choice isn't in Axis2 1.3. Contract without an implementation is useless.
On the other hand, code-first also requires you to look in the generated wsdl and verify it is interoperable. A service that can't be consumed is also useless.
So code-first or contract-first? Whatever, you'll need to do both anyway.
When working with a WCF client proxy we need to close it after usage. Failing to do so would of course affect our client performance. However it would also affect our server performance and in some cases might block new client from connecting to it. One example is when using sessions (which is the default wcf behavior): Since the open sessions number is limited a non-closed client might block a new client.
However the simple way of closing a client:
is naive. The close may fail, for example due to the client not being able to release the session because of a server problem. For this reason we need to catch any possible exception.
I've just published a post on how to use WSE3 with Visual Studio 2008. I forgot to mention that the same technique can be used to have WSE2 and VS 2005 (or even VS 2008) working together.
Microsoft has provided WSE3 a Visual Studio 2005 add-in with nice UI support. Look how nice it is:
The less nice part is that there is no such support for Visual Studio 2008 as Microsoft is encouraging us to use WCF instead. Which is a good idea generally, but not alway feasible: The reality is that a lot of the WSE3 & VS 2005 projects were migrated to VS2008 and lack this fundemental support. Also a lot of new projects need compatability with WSE3 which is not always possible with WCF.
So how WSE3 can work with VS2008?
The truth is that the WSE run time is agnostic to the IDE version. IOW projects built with VS 2008 can use WSE3 in run time in the same way as VS 2005 projects. This means we are left with the tiny mission of actually developing these projects. Well, not so tiny but also not too hard. We have two options for our needs:
Option 1 - Trainer Wheels
We need to remember that configuring WSE infrastructure is mostly a one-time mission - we do not frequently alter it during development. So we can create a VS2005 project with WSE3 and migrate it to VS2008 as is using the VS migration wizard. Usually we would never need to look at the WSE configuration until late stages. Then we can open our VS2005 project, change what we want from UI, and notice that such changes only affect this section of our web.config/app.config:
So we can copy&paste this part to our new project. In case we use a .policy file we can copy all of its contents to the new project. If this looks lame it's only because VS 2005 is strictly a trainer wheel here, we do not actually need it. For this we have:
Option 2 - Just 2008, Please
We can directly use WSE3 with VS2008 in the following way:
1. In our project, add assembly reference to "Microsoft.Web.Services3.dll" (it's in the GAC and also in %Program Files%\Microsoft WSE\v3.0)
2. If we are creating the client side we would like to use "add web reference". This is not available but luckily we have the option to use %Program Files%\Microsoft WSE\v3.0\Tools\WseWsdl3.exe:
This will create our proxy .cs file which we can add to our project. The file looks like this:
So in our code we can create a new instance of this class and call the service:
For the service side we can just create a new normal web service project, nothing special.
3. We can now use the WseConfigEditor3.exe tool that comes with the WSE3 SDK to edit our app.config/web.config and even add a policy file. Then in our client code we can tell the proxy to use this policy:
This is the same we would do with VS 2005 so no news here.
If we are on the server side we need to check both "Enable this project for Web Services Enhancements" and "Enable Microsoft Web Services Enhancements Soap Protocol Factory" in the configuration editor:
or something along these lines, and have no idea what this quota is good for, we face the temptation to put there a ridiculously large number (like 6.10* 8^23) so we would never have to it again. We should hold ourselves from doing this and put a rational number based on our needs. See the story bellow.
Ayende published an interesting post on a case where he needed to send a large number of objects between a WCF client and server. For this he had to alter some server-side default:
When he "update service reference" on his client he found out that this setting is not propagated to the clients which forces him to manually change this setting in each and every client (as stated in MSDN).
Arnon follows this up in his post and claims the following:
This setting needs to be automatically propagated to clients
There are other settings which are not propagated and needs to be, for example message size limits
The default setting should be higher (although not infinite)
I absolutely agree with the first claim. This setting is in effect both when sending and receiving data. Since in each call one party sends and another receives this setting has to be correlated between the parties. The way to dispatch this setting to clients would probably by extending the wsdl's WS-Policy with this new setting (which would be msn proprietary for that matter).
I only partially agree with Arnon's second statement. The MaxReceivedMessageSize setting (if it's the one he refers to) only affects the receiving side. There is no limit on the size of outgoing messages. Here it makes sense to have a different value for the client and the server since they probably have different capabilities in terms of hardware and they also need to handle different data.
Going back to the opening paragraph, I want to make clear the rational behind all of these settings (and me and Arnon are probably in agreement on this). These settings are not meant to directly improve the performance of the service but rather they aim to block DOS attacks. So if the limit on this setting is too high an attacker can send an XML bomb which will consume large server resources. These settings are much more important for the server then for the client, but as long as clients allow to customize them the client values do not always have to be correlated with the server ones.
Visual Studio 2008 comes with project templates for a WCF web site and a WCF service library. But what about self hosting?
I've create a simple self hosting template which you can use when starting new projects. This is useful for real projects as well as for quick POC/prototyping projects. For the latter it brings the following advantages over the out of the box templates:
It encapsulates the service as an executable so it can be easily deployed without messing with IIS (xcopy is enough)
It enables to use transports which are not supported in web sites (e.g. netTcp).