Migrating ASP.NET Web Services to WCF
27/11/2008
I am currently in the middle of a project where we are migrating a (large) amount of web services built on top of ASP.NET in .NET 2.0 (commonly referred to as ASMX Web Services) over to the Windows Communication Foundation (WCF) platform available in .NET 3.0.
The primary reason we want to do that, is because we would like to take advantage of the binary message serialization support available in WCF to speed
up communication between the services and their clients. This same technique was possible in earlier versions of the .NET Framework thanks to a technology called Remoting, which is now superceded by WCF. In both cases it requires that both the client and server run on .NET in order to work. But I digress.
Since the ASMX model has been for a long time the primary Microsoft technology for building web services on the .NET platform, I figured they must have laid out a nice migration path to bring all those web services to the new world of WCF. It turned out, they did!
The quick way
If you built your ASMX web services with code separation (that is, all programming logic resided in a separate code-behind file instead of being embedded in the ASMX file) it is possible to get an ASMX web service up and running in WCF pretty quickly by going through a few easy steps:
- Your WCF web service class no longer inherits from
the System.Web.Services.WebService class so remove it. - Change the System.Web.Services.WebService attribute on the web service class to the System.ServiceModel.ServiceContract attribute.
- Change the System.Web.Services.WebMethod attribute on each web service method to the System.ServiceModel.OperationContract attribute.
- Substitute the .ASMX file with a new .SVC file with the following header:
<% @ServiceHost Service="MyNamespace.MyService" %>
- Modify the application configuration file to create a WCF endpoint that clients will use to send their requests to:
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="MetadataEnabled"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> <services> <service name="MyNamespace.MyService" behaviorConfiguration="MetadataEnabled"> <endpoint name="HttpEndpoint" address="" binding="wsHttpBinding" contract="MyNamespace.IMyService" /> <endpoint name="HttpMetadata" address="contract" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost/myservice" /> </baseAddresses> </host> </service> </services> </system.serviceModel>
- Decorate all classes that are exchanged by the web service methods as parameters or return values with the System.RuntimeSerialization.DataContract attribute to allow them to be serialized on the wire.
- Decorate each field of the data classes with the System.RuntimeSerialization.DataMember attribute to include it in the serialized message.
Here is a summary of the changes you’ll have to make to your ASMX web service:
| Where the change applies | ASMX | WCF |
| Web service class inheritance | WebService | - |
| Web service class attribute | WebServiceAttribute | ServiceContractAttribute |
| Web service method attribute | WebMethodAttribute | OperationContractAttribute |
| Data class attribute | XmlRootAttribute | DataContractAttribute |
| Data class field attribute | XmlElementAttribute | DataMemberAttribute |
| HTTP endpoint resource | .ASMX | .SVC |
As a side note, if you are using .NET 3.5 SP1 the porting process gets a little easier, since WCF will automatically serialize any object that is part of a service interface without the need of any special metadata attached to it. This means you no longer have to decorate the classes and members exposed by a WCF service contract with the DataContract and DataMember attributes.
Important considerations
The simple process I just described works well for relatively simple web services, but in any real-world scenario you will have to take into consideration a few number of aspects:
- WCF services are not bound to the HTTP protocol as ASMX web services are. This means you can host them in any process you like, whether it be a Windows Service or a console application. In other words using Microsoft IIS is no longer a requirement, although it is a valid possibility in many situations.
- Even if WCF services are executed by the ASP.NET worker process when hosted in IIS, they do not participate in the ASP.NET HTTP Pipeline. This means that you have no longer access to the ASP.NET infrastructure services such as HttpContext, HttpSessionState, HttpApplicationState, ASP.NET Authorization and Impersonation in your WCF services.
So what if your ASMX web services are making extensive use of the ASP.NET session store or employ the ASP.NET security model? Is it a show-stopper?
Luckily enough, no. There is a solution to keep all that ASP.NET goodness working in WCF. It is called ASP.NET Compatibility Mode.
Backwards compatibility
Running WCF services with the ASP.NET Compatibility Mode enabled will integrate them in the ASP.NET HTTP Pipeline, which of course means all ASP.NET infrastructure will be back in place and available from WCF at runtime.
You can enable this mighty mode from WCF by following these steps:
- Decorate your web service class with the System.ServiceModel.Activation.AspNetCompatibilityRequirements attribute as following:
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class MyService : IMyService
{
// Service implementation
}
- Add the following setting to the application configuration file:
<system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> </system.serviceModel>
Remember that this will effectively tie the WCF runtime to the HTTP protocol, just like with ASMX web services, which means it becomes prohibited to add any non-HTTP endpoints for your WCF services.
Good luck and please, let me know your feedback!
/Enrico
REST web services
21/11/2008
If you have followed the latest advancements in the technologies and standards around web services, you must have come across the term “REST” at least more than once.
In rough terms REST is a way of building web services by relying
exclusively on the infrastructure of the World Wide Web to define operations and exchange messages. This is an alternative to “traditional” web services, which instead use a set of standardized XML dialects, WSDL and SOAP to achieve the same goals.
The reason I’m writing about REST is that if you, like me, have prematurely judged it as some kind of toy technology, you are in for a real eye-opener!
The history
First of all, let’s be clear about the origin of REST. As a term it means Representational State Transfer, as a concept it stands completely separate from web services.
It was first defined in the year 2000 by a PhD student at the University of California by the name Roy Fielding. Fielding, in his doctoral dissertation entitled Architectural Styles and the Design of Network-based Software Architectures, sought to define the architectural principles that make up the infrastructure of the most successful large-scale distributed system created by mankind: the World Wide Web.
Fielding thought that by studying the Web, he would be able to identify some key design principles that would be beneficial to any kind of distributed application with similar needs of scalability and efficiency. He referred to the result of his research as “REST”.
So, what is REST?
REST is an architectural style for building distributed systems.
The key design principle of a REST-based architecture is that its components use a uniform interface to exchange data.
Uniform interface means that all components expose the same set of operations to interact with one another. In this interface data is referred to as resources and contains three main concepts:
- A naming scheme for globally identifying resources
- A set of operations to manipulate resources
- A format to represent resources
The idea is that generalizing and standardizing the components interface reduces the overall system complexity by making it easier to identify the interactions among different parts of the system.
As of today, the Web is the only system that fully embraces the principle of unified interfaces, and it does it in the following way:
- URI is used as a naming scheme for globally identifying resources
- HTTP verbs define the available operations to manipulate resources
- HTML is the textual format used to represent resources
Applying REST to web services
Now, it is a known fact that the Web was created in order to provide a worldwide network for distributing static documents. However, it has been proven that the Web holds a potential that goes far beyond its original goal. Imagine if we could leverage the REST infrastructure of the Web to build web services. Wouldn’t that be cool?
First of all, let’s take a look at what web services are used for:
- Define a set of operations to manipulate resources
- Uniquely identify these operations so that they can be globally accessed by clients
- Use a common format to represent the resources exchanged between web services and their consumers
Well, the Web seems to have the entire infrastructure we need to accomplish all of those goals already in place. In fact the HTTP protocol defines a pretty rich interface to manipulate data. Moreover this interface maps surprisingly well to the kind of operations usually exposed by web services.
| HTTP verbs | Web Service operations |
| GET | READ |
| PUT | CREATE |
| POST | UPDATE |
| DELETE | DELETE |
Also, web services contracts are inherently accessed through URLs, it isn’t too much of a stretch to use URLs to access single operations in a contract.
Finally, web services encode the contents of their messages using SOAP, which is a XML dialect. But why do we need a whole new protocol to represent resources, when we could simply use XML as is instead?
What we just did, was applying the design principles dictated by REST to web services. The result of this process is commonly referred to as “RESTful” web services.
Wrapping up
This is how REST web services compare to traditional ones:
| Goal of web services | Traditional | REST |
| Identifying resources and operations | SOAP | URL |
| Defining operations | WSDL | HTTP |
| Representing resources | SOAP | XML |
As you can see, REST web services leverage the stability, scalability and reach offered by the same technologies and standards that power the Web today. What’s most fascinating with REST is the huge potential that comes out such a simple design.
However, don’t think even for a moment that REST will ever replace SOAP-based web services. Both architectures have their strengths and weaknesses, and REST is certainly not the right answer for all kinds of applications. I am especially thinking about corporate environments, where the needs for security and reliability are better addressed by the standards incorporated in WSDL and SOAP.
As always, the solution lies in using the right tool for the job.
/Enrico
SQL Injections
12/11/2008
When discussing web development, the subject of security inevitably comes up.
Last week while I was teaching a class in ASP.NET, we had a sample login page that, although being quite trivial in nature, was exposing a serious vulnerability to SQL injections attacks.
Does it hurt?
Well, it might. But let’s first start off by defining the concepts. An SQL Injection is a term used to define a type of attack that exploits a vulnerability in the data access layer (DAL) of an application to embed arbitrary SQL statements in properly crafted user input, that will get executed at runtime. Let me show you how this works with an example.
Vulnerability and exploit
Suppose we have a web site that prompts users to enter their username and password credentials in order to authenticate their identity. Typically, somewhere in the DAL of the application, there will be a chunk of code looking not to different than this:
using (SqlConnection connection = new SqlConnection("ConnectionString")) { string query = "SELECT EXISTS FROM Users WHERE Username='" + username + "' AND Password='" + password + "'"; SqlCommand command = new SqlCommand(connection, query); bool isAuthenticated = (bool)command.ExecuteScalar(); }
SomeUser' OR 1=1 --
SELECT EXISTS FROM Users WHERE username='SomeUser' OR 1=1 --'AND Password=''
Yes folks, this will let us login to the web site without actually possessing a valid user account.
In other scenarios SQL Injections can be used to steal information. Suppose our web site has a page displaying a list of products. The URL then could more then likely look like this:
http://unsafewebsite.com/products.aspx?category=books
Then the page would run the following piece of code to retrieve and return the appropriate rows from the database table:
using (SqlConnection connection = new SqlConnection("ConnectionString")) { string query = "SELECT * FROM Products WHERE Category='" + category + "'"; SqlCommand command = new SqlCommand(connection, query); return command.ExecuteReader(); }
An attacker could exploit the fact that the URL parameter is not properly validated and enter the following value in the browser’s address bar:
http://unsafewebsite.com/products.aspx?category=Something';SELECT * FROM Users --
Here we embedded a new SQL statement that will run after the first one during the same database connection. Again, without proper validation of the user input, the final command that will get executed at runtime will look like this:
SELECT * FROM Products WHERE Category='Something';SELECT * FROM Users --'
Which will display all information about the users of the web site on the products page. Ouch!
The solution
So, how can we prevent this from happening? Well, there are a couple of security golden rules you should keep in mind:
- Never trust user input: this means you should always assert that every single piece of data coming from the user interface is what you expect it to be, and nothing else. In some places like for example web site URLs it is a good idea to sanitize all strings by encoding them, which will replace all special characters with HTML or ASCII values. This will prevent maliciously crafted strings from being evaluated at runtime and executed as code.
- Always use parameters in SQL statements: avoid dynamically generating SQL statements in code by concatenating hard-coded strings and variables, like I showed you in the examples above. Instead you should use strongly-typed parameters that will be assigned a value at runtime. For example the following code will prevent SQL injections by only accepting numeric values for the parameter:
using (SqlConnection connection = new SqlConnection("ConnectionString")) { string query = "SELECT * FROM Products WHERE ProductId=@id"; SqlCommand command = new SqlCommand(connection, query); // Valid parameter values are only integers command.Parameters.Add("id", SqlDbType.Int, productId); return command.ExecuteReader(); }
Bringing it together
SQL injections are a relatively simple way of attacking an application by embedding SQL statements in the user input and having them execute unexpectedly. When in the wrong hands they can indeed be used for great evil. Fortunately it’s not too hard to guard ourselves from this kind of vulnerability by always validating incoming data and using parameters in all our SQL commands.
/Enrico
First preview of Windows 7
02/11/2008
On the second day of PDC 2008 in Los Angeles Microsoft gave the first public preview of the next version of their client operating system code-named Windows 7.
The demo was held in the conference’s “Big Room” and the hype was high. As I was waiting for the very first Windows 7 desktop to show up on the giant screen, I was feeling a mixture of excitement and skepticism.
Well, I didn’t have to wait long to get a grasp on Microsoft’s next client operating system. The essential nature of Windows 7, in fact, revealed itself already within the first ten minutes of the demo. Let me synthesize it for you with a simple equation:
Windows 7 = Windows Vista SP2 + Multi-touch
In my opinion Windows 7 is really what Vista should have been in its first release back in November 2006. Microsoft used this release to polish the rough edges in the operating
system like resource usage, responsiveness and user access control (UAC), amongst others. I really don’t blame them for that. They applied the hard lessons learned with Vista and used this second release to stabilize and strengthen the OS without introducing too much change. This way they hope to re-gain the users’ confidence in Windows. Here is a brief overview of some of the key improvements made in Windows 7:
- Usability
- Improved thumbnail previews in the task bar
- Possibility to collect and hide system messages in the tray bar
- Gadgets can now be placed anywhere on the desktop
- Improved dialog to customize the desktop theme
- Possibility to control how often UAC will ask you to confirm your actions
- Architecture
- Reduced memory footprint
- Reduced amount of IO operations and registry access
- Increased UI responsiveness
- Possibility to mount virtual hard-disk images (VHD) as bootable drives
But the biggest new feature Windows 7 offers customers is really native support for multi-touch computing. This means that with 7 you will be able to interact with your desktop and applications exclusively through a touch-screen. Microsoft even made available an on-screen virtual keyboard, which effectively makes the monitor the only interface needed to interact with the computer.
In my opinion this is a step in the right direction. It is evident by looking at how mobile devices have evolved in the latest years starting with Apple’s iPhone, how natural human interfaces like touch, gestures and voice is the way we will prefer to interact with computers in the future. It really feels natural to click buttons, move items and zoom documents or pictures in and out using your fingers.
All of the attendees here at PDC 2008 got a copy of the pre-beta release of Windows 7, so I will be posting a little more detailed tour of what’s in there soon.
In conclusion let me finish off this brief overview by quoting Steven Sinosfky when talking about the Windows 7 roadmap. According to him Windows 7’s development lifecycle will be divided into four main phases: pre-beta, beta, release candidate and RTM. The release dates coming out of each phase will be decided dynamically based on when the previous phase completed. Hence the final release date cannot be determined at this point in time. However he concluded saying:
“[...] we believe in shipping a new version of Windows every three years.”
And with Vista gone RTM in the fall of 2006, I’ll let you do the math.
/Enrico


