ASP.NET provides a powerful platform for developing web applications over the .NET framework. An ASP.NET web application is also a natural hosting environment for a WCF service over the web HTTP protocol, which means developers can deploy WCF services with ASP.NET web pages in the same web application side by side without any particular effort.
However, by default, some ASP.NET runtime features or state objects are not available to WCF service code even if they are within the same web application. Those limited features include:
- HttpContext is always null when accessed from within a WCF service.
- Configuration-based URL Authorization (via
<authorization>
configuration element) is not available to WCF.svc
files. These settings are ignored for WCF requests if a service resides in a URL space secured by ASP.NET's URL authorization rules. - Custom HttpModules injected into an ASP.NET application to intercept requests at later stages of the pipeline do not intercept WCF requests.
- ASP.NET-specific states such as sessionState and Application Cache are not available to WCF service codes.
Then, how can we make such features accessible to a WCF service again? Well, the WCF-service hosting infrastructure has provided a feature called ASP.NET Compatibility Mode, which can help resolve the problem. This feature is by default disabled; we will show you how to enable this feature so that the WCF service continues to enjoy the ASP.NET runtime in this recipe.
- The first thing we need to do is get an existing ASP.NET web application and then add a new WCF service into the web application. For our sample case, we will use an empty ASP.NET website with two simple ASPX pages as the hosting website. Then, a WCF service named
EchoService.svc
will be added into it so that the two ASPX web pages can run side by side with theEchoService.svc
service. The following screenshot shows the web application structure in Visual Studio Solution Explorer.The
EchoService
has a very simpleServiceContract
, which contains a singleEcho
operation to return some data of type String (refer to the following code snippet).[ServiceContract] public interface IEchoService { [OperationContract] string Echo(); }
- Now we have the ASP.NET web pages and WCF service hosting together. However, the WCF service code still cannot access those ASP.NET-specific runtime objects yet. What we need to do is apply ASP.NET Compatibility Mode into the hosting web application and the WCF service deployed in it.
To enable ASP.NET Compatibility Mode, we can simply set the
aspNetCompatibilityEnabled
attribute totrue
in the<serviceHostingEnvironment>
setting of the WCF configuration section. The following screenshot shows the configuration fragment with ASP.NET Compatibility Mode enabled.On the service implementation class of the WCF service, we need to apply the
System.ServiceModel.Activation.AspNetCompatibilityRequirements
attribute and set theRequirementsMode
property toAspNetCompatibilityRequirementsMode.Allowed
. This is quite useful, since sometimes we might not want certain WCF services to gain access to those ASP.NET runtime context objects, even if the hosting web application has ASP.NET Compatibility Mode enabled. The following code snippet shows the implementation class of the sampleEchoService
, which has applied the properAspNetCompatibilityRequirements
setting:using System.ServiceModel.Activation; [AspNetCompatibilityRequirements( RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed )] public class EchoService : IEchoService { … }
- Having all the services and applications configured appropriately, we can now start enjoying the ASP.NET context objects within the WCF service code. The following code snippet shows the sample
Echo
operation code, which collects several runtime properties from the ASP.NET request context and returns them to the service caller:public class EchoService : IEchoService { public string Echo() { var approot = HttpContext.Current.Server.MapPath("~/"); var data = HttpContext.Current.Cache["key1"]; var url = HttpContext.Current.Request.RawUrl; return string.Format("{0}, {1}, {2}", approot, data, url) ; } }
By performing a quick test on the WCF service in the WCF Test Client tool, we can get the expected response with all the ASP.NET context properties returned, as shown in the following screenshot:
WCF HTTP services hosted in an ASP.NET web application can be run in two different modes—the default mode and ASP.NET Compatibility Mode.
In the default mode, the ASP.NET runtime intercepts the WCF request in the early stage of the pipeline: BeginRequest (one of the interception points of ASP.NET HttpModule), so most of the ASP.NET Context information is not available to the WCF service code. When ASP.NET Compatibility Mode is enabled on the WCF service, the WCF service runtime hooks up into the ASP.NET HTTP pipeline through both module and handler for the HTTP transport, so those ASP.NET-specific context data become available again.
For more detailed information about ASP.NET Compatibility Mode for WCF service hosting, you can refer to the following article from Wenlong Dong's Blog:
- ASP.NET Compatibility Mode
http://blogs.msdn.com/b/wenlong/archive/2006/01/23/516041.aspx
- Using the WCF Test Client tool to test a service in Chapter 12
- Complete source code for this recipe can be found in the
\Chapter
3\recipe3\
folder