U2U Consult TechDays 2011 CD Available for Download 25 April 2011 Kris-Vandermotten .NET, Tools, WCF At TechDays 2011 in Antwerp, U2U Consult distributed a CD-ROM with two free tools. I’m happy to announce that the CD-ROM contents is now also available for download from our web site. The U2U Consult SQL Database Analyzer is a tool for SQL Server database administrators and developers. It displays diagnostic information about a database and its hosting instance that is hard to collect when you only use the standard SQL Server tools. Just point the tool at a SQL Server database of your choice, and have a look at the reports generated by the tool. The U2U Consult Code Analysis Rules for Visual Studio 2010 are a series of additional code analysis rules for Visual Studio 2010 Premium or Ultimate, and two rule sets with recommended rules for libraries and applications. The rules include additional general performance and design rules, as well as a series of rules specifically for WCF. All rules are documented on the CD-ROM. Obviously, they are applicable to all .NET languages, including C# and VB. With this CD, for the first time we make two of our own tools available to you. These are only two small components out of the U2U Consult Framework, but we hope they are as useful to you as they are to us and our clients. Enjoy.
Silverlight and the Windows Azure AppFabric Service Bus 08 February 2011 Peter-Himschoot Azure, WPF/Silverlight, .NET Development, WCF This blog post will show you how to allow a Silverlight application to call a service over the Windows Azure AppFabric Service Bus. The problem you need to solve is that Silverlight will look for a “clientaccesspolicy.xml” at the root uri of the service. When I tried it myself I couldn’t find any “how to” on this topic so I decided to turn this into a blog post. If anyone else has this blogged, sorry I am such a bad internet searcher . So, you’ve just build a nice Silverlight application that uses some WCF service you’re hosting locally. You’ve done all the steps to make it work on your machine, including the “clientaccesspolicy.xml” to enable cross-domain communication. The only thing is that you want to keep hosting the service locally and/or move it to another machine without updating the Silverlight client. You’ve heard that the Windows Azure Service Bus allows you to do this more easily so you decide to use it. This is your current service configuration (notice the localhost address!). Code Snippet <service name="SilverlightAndAppFabric.TheService" > <endpoint name="HELLO" address="http://localhost:1234/rest" behaviorConfiguration="REST" binding="webHttpBinding" bindingConfiguration="default" contract="SilverlightAndAppFabric.IHello" /> </service> What you now need to do is to move it to the AppFabric Service bus. This is easy. Of course you need to get a subscription for Windows Azure and set up the AppFabric service bus… Look for somewhere else on this, there’s lots of this around. Then you change the address, binding and behavior like this: You need an endpoint behavior, because your service needs to authenticate to the service bus (so they can send you the bill): Code Snippet <endpointBehaviors> <behavior name="REST"> <webHttp /> <transportClientEndpointBehavior> <clientCredentials> <sharedSecret issuerName="owner" issuerSecret="---your secret key here please---" /> </clientCredentials> </transportClientEndpointBehavior> </behavior> </endpointBehaviors> You (might) need a binding configuration to allow clients to access your service anonymously: Code Snippet <webHttpRelayBinding> <binding name="default" > <security relayClientAuthenticationType="None"> </security> </binding> </webHttpRelayBinding> And of course you need to change the endpoint to use the WebHttpRelayBinding: Code Snippet <endpoint name="HELLO" address="https://u2utraining.servicebus.windows.net/rest" behaviorConfiguration="REST" binding="webHttpRelayBinding" bindingConfiguration="default" contract="SilverlightAndAppFabric.IHello" /> This should to the trick. Yes, when you try the REST service using Internet Explorer you get back the intended result. Now you update the address in your Silverlight application to use the service bus endpoint: This is the old call: Code Snippet wc.DownloadStringAsync(new Uri("http://localhost:1234/rest/hello")); And you change it to: Code Snippet wc.DownloadStringAsync(new Uri("https://u2utraining.servicebus.windows.net/rest/hello")); Please note the switch to https and the service bus address. You run your Silverlight client and it fails with some strange security error! The problem is that Silverlight will try to access the clientaccesspolicy.xml file from your new address. Since this is now the service bus this will not work. To solve it you simply add another REST endpoint that will return the clientaccesspolicy from this Uri. Start with the service contract: Code Snippet [ServiceContract] public interface IClientAccessPolicy { [OperationContract] [WebGet(UriTemplate = "clientaccesspolicy.xml")] Message GetPolicyFile(); } Implement it: Code Snippet public Message GetPolicyFile() { WebOperationContext.Current.OutgoingRequest.ContentType = "text/xml"; using (FileStream stream = File.Open("clientaccesspolicy.xml", FileMode.Open)) { using (XmlReader xmlReader = XmlReader.Create(stream)) { Message m = Message.CreateMessage(MessageVersion.None, "", xmlReader); using (MessageBuffer buffer = m.CreateBufferedCopy(1000)) { return buffer.CreateMessage(); } } } } And make sure it returns the right policy. This is what gave me a lot of headache, so here it is: Code Snippet <?xml version="1.0" encoding="utf-8"?> <access-policy> <cross-domain-access> <policy> <allow-from http-request-headers="*"> <domain uri="http://*"/> <domain uri="https://*"/> </allow-from> <grant-to> <resource path="/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access> </access-policy> Pay special attention to the allow-from element. By default this will allow SOAP calls, not REST calls. For explanations read the documentation. You might want to edit it anyway. Now add a similar REST endpoint, making sure the clientaccesspolicy is at the root level: Code Snippet <endpoint name="CLIENTACCESSPOLICY" address="https://u2utraining.servicebus.windows.net" behaviorConfiguration="REST" binding="webHttpRelayBinding" bindingConfiguration="default" contract="SilverlightAndAppFabric.IClientAccessPolicy" /> Done! A working example (you will have to change the client credentials to your own) can be downloaded from the U2U site here.
Azure Inter-role communication using callback instead of queues 20 December 2010 Peter-Himschoot Azure, WCF, VS2010, .NET Development I’m currently playing with Azure and the Azure training kit, and I learned something cool today. When you work with Azure you can setup multiple worker roles for your Azure application. If you want to make these roles talk to one another you can use the queuing mechanism which is part of Azure. But you can also use WCF dual interface mechanism. Imagine you want to build a chat application using Azure and WCF. In this case you define a worker role that exposes a dual interface like this: Code Snippet [ServiceContract( Namespace = "urn:WindowsAzurePlatformKit:Labs:AzureTalk:2009:10", CallbackContract = typeof(IClientNotification), SessionMode = SessionMode.Required)] public interface IChatService { /// <summary> /// Called by client to announce they are connected at this chat endpoint. /// </summary> /// <param name="userName">The user name of the client.</param> /// <returns>The ClientInformation object for the new session.</returns> [OperationContract(IsInitiating = true)] ClientInformation Register(string userName); /// <summary> /// Sends a message to a user. /// </summary> /// <param name="message">The message to send.</param> /// <param name="sessionId">The recipient's session ID.</param> [OperationContract(IsInitiating = false)] void SendMessage(string message, string sessionId); /// <summary> /// Returns a list of connected clients. /// </summary> /// <returns>The list of active sessions.</returns> [OperationContract(IsInitiating = false)] IEnumerable<ClientInformation> GetConnectedClients(); } The IClientNotification interface is the call-back interface which is implemented by the client of the service. The client calls the Register method on the server, which then can keep track of the client by using the callback interface: Code Snippet IClientNotification callback = OperationContext.Current.GetCallbackChannel<IClientNotification>(); If you host the service as a single instance, all clients will register to the same service, so this service can easily track each client. But if you grow and start using multiple instances of your service in Azure, each client will register to a single instance, so each instance will know only about its own clients. If two clients, registered to different instances, want to communicate, the services will have to handle the communication for this. The solution is easy, make them also expose the IClientNotification callback service interface using internal endpoints, so they can communicate to each other: Code Snippet public class ChatService : IChatService, IClientNotification Of course each service will have to be able to find the other service instances. This you can do with the RoleEnvironment class, which you can use in your worker role class: Code Snippet var current = RoleEnvironment.CurrentRoleInstance; var endPoints = current.Role.Instances .Where(instance => instance != current) .Select(instance => instance.InstanceEndpoints["NotificationService"]); This does require the worker role to define an internal endpoint. You can do this in Visual Studio 2010. Select the worker role’s properties, go to the endpoint tab and enter an internal endpoint: The rest of the code is straightforward (of your comfortable with WCF that is) and can be found in the Azure Training Kit (look for the Worker Role Communication lab).
Safe disposal of WCF proxies 28 September 2010 Kris-Vandermotten WCF The issue has been known for a long time: you cannot safely dispose a WCF proxy that inherits from ClientBase<T> with a using statement, because the dispose method may throw. For more information, see http://www.google.com/search?q=wcf+proxy+dispose. However, I’ve always found most solutions out there to be too complex, too cumbersome, or both. Some of them even seek to replace the Visual Studio (or svcutil.exe) generated proxy by handwritten code, in which case you loose the convenience of the “Add Service Reference” dialog and the automatic configuration file generation. I wanted a simple but effective solution that does not replace the Visual Studio code generation, and is easy to use at the same time. I came up with a simple extension method, that you use as follows: var proxy = new SomeServiceClient(); using (proxy.SafeDisposer()) { // use the proxy here } Here’s the code: namespace U2UConsult.ServiceModel { using System; using System.Diagnostics; using System.ServiceModel; public static class ClientBaseExtensions { private static readonly TraceSource traceSource = new TraceSource("U2UConsult.ServiceModel"); public static IDisposable SafeDisposer<T>(this ClientBase<T> proxy) where T : class { return new SafeDisposerProxy<T>(proxy); } private sealed class SafeDisposerProxy<T> : IDisposable where T : class { private ClientBase<T> proxy; public SafeDisposerProxy(ClientBase<T> proxy) { this.proxy = proxy; } public void Dispose() { if (this.proxy != null) { if (this.proxy.State == CommunicationState.Opened) { try { this.proxy.Close(); } catch (Exception ex) { ClientBaseExtensions.traceSource.TraceEvent( TraceEventType.Error, 0, "Could not close client proxy, reason: {0}", ex.Message); this.proxy.Abort(); } } else { this.proxy.Abort(); } this.proxy = null; } } } } } Enjoy!
Fixing Application Pool not starting problem by editing ApplicationHost.config 21 March 2010 Peter-Himschoot .NET Development, AppFabric, WCF While playing around with Windows Server AppFabric I created a new Application pool set for .NET 4. However this application pool would immediately throw an error when starting; “The worker process failed to pre-load .Net Runtime version v4.0.21006.” A little experimentation showed that changing to the built in application pool worked. So it looks like IIS, when creating a new application pool, configures for the wrong .NET version. I then found that this kind of information is stored in ApplicationHost.config, but I couldn’t find it anywhere on my system (except backups in history). Hmmm. And I wasn’t the only one. So using notepad (!) I could open this file in “C:\Windows\System32\inetsrv\config”. Best of course is to first stop IIS and make a backup of the file. Then I edited the <applicationPools> section, looking for v4.0 and replacing it with v4.0.30128. And yes! That fixed it.
Configuring your WFC and WF4 services using AppFabric 19 March 2010 Peter-Himschoot VS2010, WCF, WF 4, .NET Development, AppFabric Configuring your services Normally I configure my services using Visual Studio (and type-ing in the configuration as Xml) or using the WCF Service Configuration tool. AppFabric also allows you to configure your services, directly from IIS (making it a nice integrated experience!). The difference is in that AppFabric exposes the stuff an it-pro needs to look at the health of an application more… Developers are more interested in making it work, productions is more interested in keeping it working… <grin> You can setup a persistance and tracking store (actually databases) to make your services trackable and durable. This will also make it easier (or less hard) to see why your service is no longer functioning the way it should. Of course you can still setup the System.Diagnostics tracing, but this again is more for developers. Some preparations are needed AppFabric uses the net.pipe protocol to manage your services (through standard endpoints), so you might need to enable this on IIS. Select your site, then select Edit Bindings… The following window should open: If net.pipe is not listed, hit the Add… button and select net.pipe. Use * for Binding information. Then go to your service and select Advanced Settings… The dialog should open: Add net.pipe to the list of Enabled Protocols. You might also need to run the AppFabric system-level configuration. To do this, go to Start->All Programs->Windows Server AppFabric->Configure AppFabric. The configuration utility should launch: Hit Next: Here you can configure the monitoring and persistance databases. Check the Set Monitoring configuration check-box, select the account you want to use and the provider (there is one default, which will store everything in a SQL server database: Hit the Configure… button. Configure as follows (replacing Peter-PC with your domain/machine name): Hit Ok. Check the results. You might get an ‘the database already exists’ kind of warning. Simply continue… Continue through the wizard… Configuring a WCF service In IIS, select your site or service (and most of this can also be done at other levels), and then in the actions pane select “Manage WCF and WF Service->Configure…” This opens the “Configure WCF and WF for Site” dialog: Check the “Enable metadata over HTTP” to set the ServiceMetadata behavior. Over to the Monitoring tab: Keep the checkbox checked if you want monitoring records written to the monitoring database. Using the level you can change from monitoring everything to nothing… You can also configure the usual WCF tracing and message logging here. The throttling tab allows you to limit the number of requests and service instances, while the security tab allows you to set/change the service certificate. A later post will be about configuring WCF and Workflow services…
Windows Server AppFabric Beta 2: Deploying services 14 March 2010 Peter-Himschoot AppFabric, VS2010, WCF, WF 4, .NET Development Microsoft released Visual Studio 2010 RC a while ago, but unfortunately this broke Windows Server AppFabric beta 1. Luckily march 1 MS released beta 2, which works with VS 2010 RC. I’ve installed it and will now try to show you a couple of things. So what is AppFabric? To be honest, there is another AppFabric, the one for Azure, and that is not the one I am talking about. What is Windows Server AppFabric? AppFabric makes installing, administering, monitoring and fixing problems in WCF 4 (!Yes, only starting at .NET 4) services a lot easier by extending IIS and WAS (Windows Activation Services, which are used to host non-HTTP WCF services in IIS). It also adds a distributed caching mechanism (also known as Project Velocity) to make it easier to scale ASP.NET and WCF services. If you’re familiar with BizTalk 2006/2009, you’ll know that the BizTalk Administration application shows you each BizTalk application’s health, what went wrong, how many were executed, etc… AppFabric gives you the same but now for WCF and WF 4 services. Look at this screen shot: As you can see, after installing AppFabric IIS is now showing these new icons: AppFabric Dashboard, Endpoints and Services. The dashboard will show you the current status of your services (running, stopped, with errors, etc…). Endpoints and Services allow you to list and configure the endpoints and services. Deploying using AppFabric AppFabric Hosting Services provides easier deployment of services: First thing you need to do is to package your WCF service. To do this go to the project properties and select the new Package/Publish tab: You can now select where to create the package (and if your want it as a .zip file) and how to deploy it in IIS. Now you need to create the deployment package in Visual Studio 2010: Now we can import the application using IIS: This will open the Import Application Package dialog. Use the browse button to open the package .zip file: Hit next: And Next again: Note that the service name is taken from the package properties. Hit next again, hopefully your services will deploy successfully. To verify this, you can go to your site in IIS: And click on Services. You should see your service listed (for example I have three services running here): You can also click on Endpoints to see the list of endpoints: Because of WCF default endpoints you get 4 different endpoints per service; you can modify which types of default endpoints you want, but that is now what I’ll be showing you here. A note on using your own application pool with AppFabric During my experiments I created a new AppPool for my services. When testing my service, I would always get the following error: HTTP Error 503. The service is unavailable. First I thought the solution would be easy. My application pool was stopped. Starting it should fix the problem. But it didn’t. So I investigated a little further. Seems that my new application pool tries to use .NET 4 version 21006 (beta 2?). I could see this in the Event Viewer: The worker process failed to pre-load .Net Runtime version v4.0.21006. I think something didn’t (un)install during my migration to .NET 4 RC. So I’m now using the ASP.NET 4 application pool…
Techdays 2010 26 January 2010 Peter-Himschoot .NET Development, VS2010, WCF, WF 4 I’m happy to say I’ll be speaking at TechDays 2010 in Belgium and DevDays 2010 in the Netherlands. In Belgium I’ll be doing one session on “What is new in WCF 4” and one session on “Workflow Foundation 4”. In the Netherlands I’ll do on session on “What is new in WCF4” and one on “Developing for Windows 7 with the Windows API code pack”.
WCF and large messages 23 January 2010 Peter-Himschoot WCF, VS2010, .NET Development, Entity Framework This week I’ve been training a couple of people on how to use .NET, WCF4, Entity Framework 4 and other technologies to build an Enterprise Application. One of the things we did was return all rows from a table, and this table contains about 2500 rows. We’re using the Entity Framework 4 self-tracking entities which also serialize all changes made it the objects. And I kept getting this error: The underlying connection was closed: The connection was closed unexpectedly. Server stack trace: at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason) at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout) at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout) at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) At first I thought it was something to do with the maximum message size, another kind of error you get when sending large messages. The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element. Server stack trace: at System.ServiceModel.Channels.HttpInput.ThrowMaxReceivedMessageSizeExceeded() at System.ServiceModel.Channels.HttpInput.GetMessageBuffer() at System.ServiceModel.Channels.HttpInput.ReadBufferedMessage(Stream inputStream) This one is easy to fix (although a little confusing because you have to configure the binding of the receiving side of the message, which is most of the time the client: But doing this didn’t help. So what was it? I knew the size of the message couldn’t be the problem, because I’d sent way bigger messages before. Maybe there was something in the contents that made the DataContractSerializer crash? Checking this is easy, I wrote a little code that would make the serializer write everything to a stream and see what happens. Works fine. Hmmm. What could it be? So I went over the list of properties of the DataContractSerializer. I has a MaxItemsInObjectGraph property. Maybe that was it, but how can I change this number? Looking at the behaviors I found it. What you need to do when you send a large number of objects is you have to increate this number, which is easy. At the server side you use the DataContractSerializer service behavior and set its value to a large enough number: At the clients side you use the DataContractSerializer endpoint behavior. That fixed my problem.
Adding Error Handling to content based routing with WCF 12 October 2009 Peter-Himschoot WCF Yesterday I blogged about content based routing with WCF. Today I want to talk about error handling. What if you route to a service that is not available. WCF allows you to define backup services using a backup list. So let’s do this: start by building a compatible backup service. In this case I will be using named pipes because this is a very reliable transport: static Uri ServiceUri = new Uri("net.pipe://localhost/BackupProductService"); static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(BackupProductsService), ServiceUri)) { host.Open(); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Backup product service is running"); Console.ReadKey(); } } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Now let’s create the backup list in the routing service’s configuration: <routing> <backupLists> <backupList name="backup"> <add endpointName="backup" /> </backupList> </backupLists> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } This adds a backup endpoint called “backup” which we of course also need to add the the client endpoints: <client> <endpoint address="net.tcp://localhost:8010/ProductService1" binding="netTcpBinding" contract="*" name="toys" /> <endpoint address="net.tcp://localhost:8011/ProductService2" binding="netTcpBinding" contract="*" name="beverages" /> <endpoint address="net.pipe://localhost/BackupProductService" binding="netNamedPipeBinding" contract="*" name="backup" /> </client> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Finally we add the backup list to the filterTable: <filterTables> <filterTable name="productRouting"> <add filterName="filterToys" endpointName="toys" backupList="backup" /> <add filterName="noToys" endpointName="beverages" backupList="backup" /> </filterTable> </filterTables> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } If we now run the sample, but without the toys or beverages service, routing will automatically divert to the backup service.