making a WCF REST stand-alone service exe from scratch – part 4 of 4, separating out the client and interface

From the previous work, we have a WCF REST service in a console app and we have a client, but one could argue it’s not ‘real’ yet because, well, they’re both in the same console app.

To alleviate that concern, we’ll go ahead and make it ‘real’ by doing the following:

  • moving the client out to a separate console app
  • creating a shared class lib for the interface to live in
    • NOTE: the client could just refer to the existing service project fine, but that’s still kind of cheating, so we’ll not do that
  • moving the client configuration over to the new client app
  • configuring the solution to start both apps

So, let’s add the client exe first:

image

image

Much like the service console exe, we’ll want to change it from the client profile to the full framework. 

image

While you might think the client profile would be enough for a WCF client, there’s a bit of a ‘viral’ thing going on that requires the full framework even for our client:

  • The client profile includes assembly System.ServiceModel, but does NOT include System.ServiceModel.Web
  • Our interface includes use of the WebGet attribute, and that’s in System.ServiceModel.Web
  • Because we’re using that interface, whatever project holds the interface (whether a separate ‘shared’ library or not) will need to use the full framework so it can use that attribute
  • The client project which uses the interface will therefore also need the full framework, since the client profile framework can clearly not load assemblies that depend on the full framework

Being a console exe, the client console exe defaults targeting x86 (32-bit) and while we could change it, we don’t really have a need to do so any more, so I’ll leave it as 32-bit:

image

Now we’ll go ahead and create the ‘shared’ project (also with the full framework, see above) to stick the interface in as well and move the interface to that project (and namespace, to make it more ‘real’ 🙂

image

Since the interface moved (project and namespace), we broke our service project, but we just need to add a project reference and ‘using’, but ReSharper is nice enough to do both for us:

image

While we’re moving code around, we’ll go ahead and move the client code (the stuff inside the ‘using’ of the channel factory) to the client console exe.

class Program
{
    static void Main(string[] args)
    {
        using (var channelFactory = new ChannelFactory<IMyService>(""))
        {
            var channel = channelFactory.CreateChannel();
            var response = channel.AnswerBack("blah");
            Console.WriteLine("Got response of {0}", response);
        }
    }
}

What’s left in our service exe?  We just need to make sure we have something that blocks (Console.ReadLine is fine) to keep our service host open:

class Program
{
    static void Main(string[] args)
    {
        using (var serviceHost = new ServiceHost(typeof(MyService)))
        {
            serviceHost.Open();
            Console.WriteLine("Hit Enter when done");
            Console.ReadLine();
        }
    }
}

Back in the client exe, I let ReSharper add a couple of references and ‘using’ statements here, too (obviously you could do these manually too)

image

image

At this point everything should be building.

image

However, as you might expect, just hitting F5 doesn’t really do anything – when we changed the fully-qualfiied name for the service contract, VS / R# didn’t update the service exe config, so even just running the service exe fails:

image

Since we know that we changed the fully-qualified name so the namespace is now ‘SharedLib’ instead, we’ll just manually edit the app.config to make that change.  Since we haven’t moved the client config over to the new client console exe yet, we need to fix it in 2 places in this app.config, the service and the client:

  <system.serviceModel>
    <client>
      <endpoint 
        name="ourWcfRestClientEndpoint"
        address="http://localhost/testing" 
        contract="SharedLib.IMyService" 
        kind="webHttpEndpoint" />
    </client>
    <services>
      <service name="SimpleWcfRestServiceConsoleApp.MyService">
        <endpoint
          address="http://localhost/testing"
          contract="SharedLib.IMyService"
          kind="webHttpEndpoint" />
      </service>
    </services>
  </system.serviceModel>

Once we fix that, the service will run just fine and we can call it from the browser:

image

image

But wait, we have this great client console app – let’s have it run too 🙂

If we just want a one-time run (the service exe is still running), we can just run it via the Debug context submenu:

image

image

However, more typically we’d want both the client and server to run when we hit F5, so we’ll go into the solution properties and tell it to start both of them:

image

But what happens if we hit F5 now?  Well, we’re not giving the service any time to get going, so the client will do the request before the service is actually listening, causing us to get an endpoint exception:

image

The simplest fix is to just add a sleep in the client to give the service a few seconds to start up before we do the call 🙂

image

With that in place, we can now hit F5 and get what we expected – the server runs, then the client makes its request:

image

There you have it – a simple, from-scratch WCF REST service, hosted in a console app.  Have fun!

making a WCF REST stand-alone service exe from scratch – part 3 of 4, creating client configuration

Now that we have a real interface for the service contract, we can use ChannelFactory to talk to it!  So what happens if we try to use it right now?  Well, we haven’t made any configuration for the client, so understandably we get an exception:

image[122][2]

Now, in this case we happen to be in the code that has access to the service host, and as such we can just pass in the endpoint to the channel factory since it can figure out everything from that:

image[125][2]

image[128][2]

That works, but obviously it’s “cheating” since normally clients won’t have access to the service host, so we should do the actual client configuration instead 🙂

This is one of the real strengths of the Service Config Editor – if you point it at a service config, it can generate the client config for you.  (Sweet!)

Normally the client would be in a separate project, but we’ll do it in the same project for now to keep it simpler for now (we’ll separate it out later)

image[131][2]

image[134][2]

After browsing to and selecting the app.config for our service:

image

(it’s the only entry in the drop-down since we only have one service endpoint)

You can choose a different name, but I stick with the default here.

NOTE: while it says ‘(Default)’ it actually means the default, which is an empty string.  This could be understandably confusing. 🙂

image[140][2]

 image

We can check what’s added in the app.config:

    <client>
      <endpoint address="http://localhost/testing" binding="" bindingConfiguration=""
        contract="SimpleWcfRestServiceConsoleApp.MyService" name=""
        kind="webHttpEndpoint" endpointConfiguration="">
        <identity>
          <certificateReference storeName="My" storeLocation="LocalMachine"
            x509FindType="FindBySubjectDistinguishedName" />
        </identity>
      </endpoint>
    </client>

Notice that we’re also using the standard webHttp endpoint (the ‘kind’ attribute, just like in our service config).

I’m not a fan of the empty attributes included nor the identity cert stuff, and since I don’t plan on using those, while I could change the identity stuff in the service config editor, I’ll just edit the XML to clean it up:

    <client>
      <endpoint 
        address="http://localhost/testing" 
        contract="SimpleWcfRestServiceConsoleApp.MyService" 
        kind="webHttpEndpoint" />
    </client>

Now the WCF REST client calls (using ChannelFactory!) will work.

image[149][2]

NOTE: we’re passing an endpoint configuration name, it just happens to be an empty string since we didn’t specify a non-default name.  That is NOT the same thing as not specifying a configuration name at all, since doing so will (still) result in an exception since there’s no configuration specified:

image[158][2]

If we don’t like that (default) endpoint config name (empty string) we can just change it to add a specific name, of course:

    <client>
      <endpoint 
        name="ourWcfRestClientEndpoint"
        address="http://localhost/testing" 
        contract="SimpleWcfRestServiceConsoleApp.MyService" 
        kind="webHttpEndpoint" />
    </client>

Now we can use that name in our ctor call:

image[155][2]

making a WCF REST stand-alone service exe from scratch – part 2 of 4, extract a service contract interface

Extracting out an interface

In Part 1 we created the base WCF service inside a console app then showed it working from a web browser.  That’s nice, but it’s There’s one non-minimal change I wanted to get included here since I think it’s something most any WCF app will do – use a ‘real’ interface for the service contract.  There’s a few nice benefits of having the service contract be an interface instead of the actual concrete type like we did above:

  • We can move the WCF attributes (ServiceContract, WebGet, etc) into the interface and leave our service as just an implementation
  • We can put the interface in an assembly that we share with clients without having to share the actual service code with them
  • (biggest one IMHO) we get to use ChannelFactory to call our WCF REST service 🙂

ChannelFactory is an extremely useful class that lets you deal with the WCF service as an API (through the service contract interface) instead of dealing with any of the underlying mechanics of how to talk to it or having to generate a proxy (using svcutil or add service reference or whatever).  You generally just create a factory, call its CreateChannel which returns an instance of your interface, and then use it as you would any other “normal” interface, just like it was a local object:

image[104]

However, one of ChannelFactory’s requirements is that you’re using an actual interface to talk to the service.  Given what it does (CreateChannel returning an instance of the generic type you provide), hopefully that makes sense, since without this restriction the CreateChannel would need to return back an instance of the actual service class (!)

So, if you try to use ChannelFactory with the code as it is now, it’ll throw since we’re specifying the type to the factory as the actual service class (since we currently lack a separate contract interface)

 image[107]

So, lets extract out that service contract interface now.

While we would normally move it to another assembly that would be shared between the client and server, we’ll skip creating another class library for now and just do it in the same project.

I’m going to let ReSharper do the extract interface for me:

image[110]

However, it doesn’t do quite what I wanted – it duplicated the WebGet attribute (instead of only keeping it in the interface) and didn’t do anything with the class-level attributes at all.  So, I manually move those over after the extract, so we end up with a class that just implements the interface:

public class MyService : IMyService
{
    public string AnswerBack(string something)
    {
        return "You said: " + something;
    }
}

And an interface that includes the WCF bits:

[ServiceContract]
public interface IMyService
{
    [WebGet(UriTemplate = "say/{something}")]
    string AnswerBack(string something);
}

Switching the service contract to the extracted interface

Now that we have this separate interface, we need to go change the service endpoint to use this new interface as the contract.  First, rebuild so we’ll be able to just browse to the new contract :)  Then, open the config again (if you closed it)

 image

Now when browsing into the built exe, I see the interface we just extracted, and can choose that as the service contract:

image[116]

(Yes, I could have just edited the xml and added the ‘I’ but I wanted to show this method of doing so)

image[119]

making a WCF REST stand-alone service exe from scratch – part 1 of 4, creating the minimal bare service

If you search the online templates in VS2010, you’ll find a WCF REST template already there.

image

However, this template makes an ASP.NET-hosted (typically IIS-hosted) service for you.  For instance, it uses ASP.NET support for things like creating a route for the service:

public class Global : HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes();
    }

    private void RegisterRoutes()
    {
        // Edit the base address of Service1 by replacing the "Service1" string below
        RouteTable.Routes.Add(new ServiceRoute("Service1", new WebServiceHostFactory(), typeof(Service1)));
    }
}

It also adds in the modules bit for the url routing support, used above:

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>

You can also see how its WCF config section (system.serviceModel) needs asp.net compat, although it’s VERY simple on the WCF config side since it just defines a simple WCF REST standard endpoint (webHttpEndpoint) and the ‘heavy lifting’ is done by the ServiceRoute and resulting WebServiceHostFactory, as per the RegisterRoutes method.  It’s also a bit simplified since the template has a single service class, but no service contract involved.

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <standardEndpoints>
      <webHttpEndpoint>
        <!-- 
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

All that’s fine if you’re ok hosting inside a web server, but what if you wanted to just host the service in your own exe (console app, windows service, winforms/wpf, whatever) that isn’t in a web server? (in particular, WCF won’t be using ASP.NET)

Creating our console WCF-service app

We’ll start off by creating a console app, not reusing anything from the existing WCF REST template or anything else:

image

Since we’re going to make a service, first thing we’ll want to do is switch over the framework to the ‘full’ framework instead of the client profile that console apps default to:

image

Using ‘Add Reference’ (the Pro Power Tools version), you can search on ServiceModel and just add the base, activation, channels, and web.

 image

While you can configure WCF programmatically (I might do a post about that), we’re going to stick with keeping our configuration in the config files so we can use the service config editor to make the changes.

Creating our bare-bones WCF service class

First, lets make a service to expose.  I’ll add a new class called MyService (can be called anything), mark it public (so the WCF framework can instantiate it) and add the [ServiceContract] attribute to mark it as, well, a service contract 🙂

I then add a method with a WebGet attribute to say this method should be callable via the http GET verb, and specify a template (this one passes a parameter, but templates are very flexible)

[ServiceContract]
public class MyService
{
    [WebGet(UriTemplate = "say/{something}")]
    public string AnswerBack(string something)
    {
        return "You said: " + something;
    }
}

Creating our service host

Now that we have a bare minimum service, let’s expose it with a service host in our Program.cs.  There’s generally 2 options for creating your service hosts – create them manually (invoke the constructor) or use one of factories (ServiceHostFactory, WebServiceHostFactory).

If you use the ctor manually, you have to specify either the type or the actual singleton instance of the service (the singleton path is pretty rare, the latter is what we will use)

image

If we wanted to avoid encoding the type here and would rather put it into the config, theoretically we could use one of the service host factories instead. Unfortunately, the ServiceHostFactory (and WebServiceHostFactory) are limited to working within ‘hosted’ environments (IIS, WAS) so trying that route throws an exception:

image

So, for now we’re stuck with making the ServiceHost instance ourselves and specifying the type.

image

We could even pass in the address(es) for the service if we wanted (as per the baseAddresses arg above), but for now we’ll stick with doing that in the config, so our Program.cs is as above.

Configuring our WCF service

If you try to run the service now (when we haven’t configured any addresses for it), you get an exception, as you would expect:

image 

Ok, so now we need to add some configuration for our service.  We’ll use the Service Config Editor on the app.config file that’s already in place:

We’ll let it create a new service for us:

image

Specify our type:

image

NOTE: if you’re on a 64-bit OS (and therefore you’re presumably running the 64-bit SvcConfigEditor and want ‘Browse’ to work and be able to open the console exe, you’ll need to make sure you changed the project platform target to Any CPU or x64 since the default (x86) won’t load in the (64-bit) SvcConfigEditor.  You’ll get an exception like:

image

While it kills edit-and-continue to switch away from 32-bit like this, I’m fine switching the app to Any CPU:

image

Then (after rebuilding the project) the browser can load the exe and see the type inside:

image

NOTE: this is just for the config editor app to be able to browse into the exe – it isn’t necessary for the actual runtime, as you can just specify the type name (or not use the config editor, obviously 🙂

Now for the service contract, we’re in the simple case of not having a separate service contract, so it’s the same type:

image

Communication mode is HTTP (the default)

image

And here’s the page I hate – pick your web service interop choice.  ‘None’ isn’t an option here, you’re stuck picking one or the other, so I just leave the default of Basic (knowing I’ll remove it when editing the config later)

image

Now pick an address – I like ‘localhost/testing’ but whatever is fine.  Note that it can be something on port 80 (or any other already-used port) because the http.sys support in the kernel lets you register for url’s “below” the normal application port-binding logic, so you could have any number of different apps all ‘listening’ on port 80 –based (or any other port) url’s.  This was really weird to me when I was first getting used to it a few years ago, but it’s very useful 🙂

image

Summary page tells us what we chose:

image

After Finish, we can see that it created a service for us, and the binding currently in place is (as we saw) a basicHttpBinding:

image

At this point, there’s 2 ways of getting to a working WCF REST configuration:

Option 1: switch the binding to webHttpBinding, AND add the webHttp behavior to the endpoint configuration

OR

Option 2: use the webHttpEndpoint standard endpoint which automatically includes the webHttp behavior.

Since there’s not really much to gain from doing the extra work of doing the binding and behavior manually, we’ll just go with Option 2 and use the standard endpoint.

Changing our existing endpoint to use the standard endpoint is very simple – just clear the Binding that’s there and then set the Kind:

image

image

And there we go – now when we run the app, the service is up and running and waiting for our REST calls – since we have this one GET call defined, we can just invoke it with a browser:

image

Looking at the config that was generated

We used the service config editor to create this config, but what was the actual generated config?  We can check it out just looking at the app.config, of course:

  <system.serviceModel>
    <services>
      <service name="SimpleWcfRestServiceConsoleApp.MyService">
        <endpoint 
          address="http://localhost/testing" 
          contract="SimpleWcfRestServiceConsoleApp.MyService"
          kind="webHttpEndpoint" />
      </service>
    </services>
  </system.serviceModel>

It’s pretty straightforward – thanks to being able to use the standard endpoint (the ‘kind’ attribute), it’s just the address and the service type.

debugging WCF? Use the SvcConfigEditor, right from VS!

This isn’t a new ‘trick’ per se, but enough people either don’t know or don’t remember about it, so I’ll make a post 🙂

If you’re doing WCF services of any type (inside IIS or not, WS* or REST or whatever) you likely have an app.config or web.config (or both, depending on how you’re configuring your clients) that holds your system.serviceModel configuration (your WCF config).

The WCF configuration is very powerful and flexible, but as such can be difficult to work with manually. That’s where SvcConfigEditor comes in, helping to at least make it a little more manageable than editing the config xml manually when trying to get your WCF server or client configured.

First, where is it?  You can find it inside the start menu:

image

You can also run it from the VS command prompt (just type ‘svcconfigeditor’).  In both cases, you’re running what’s at this path (for me, on x64 OS)

» dir -r -fi SvcConfigEditor.exe | f
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\SvcConfigEditor.exe
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\SvcConfigEditor.exe

Now, you can certainly just run the exe and point it at the config you want to edit, but VS lets you do ‘Open With’ for files, so we can add SvcConfigEditor there and then be able to do the WCF config editing right from VS.

First, right-click on the config file (web.config or app.config or whatever) that contains your WCF config and choose ‘Open With’:

image

It will default to the XML editor for the config file:

image

However, we want to add a new tool to that list, so we choose ‘add’ and then put in the path to the editor and a friendly name for the list:

image

image

You could click ‘Set as Default’ here, too, but I like keeping the XML editor as the default, so I don’t.

Since the new entry is now selected, we can just click OK and have the config open in the editor:

image

There’s lots of goodness in the config, but the real treat is under Diagnostics where you can turn on lots of different kinds of options around message logging and end-to-end tracing:

image

 

image

another R# bug blog post, move along :)

This one’s related to the multi-line insert in VS2010.  It seems like there’s multiple points at which R# considers the current expression ‘completed’ and does a little rewriting, but that R# rewriting doesn’t current seem to understand that the change that just happened may have happened to multiple other lines, and kills all but one of them.

Start out with something simple (ignore that you’d instead do stream.Read)

image

Get ready to do a multi-line insert to put a cast in front of the 4 calls:

  • put the cursor in front of the first stream.ReadByte call
  • hold down Shift+Alt and tap down-arrow 3 times

Now you have a zero-width selection before all 4 stream.ReadByte calls:

image

Now you can type the cast you want to do on all 4 lines, which is to cast it to byte:

image

Up until we type that last ‘)’ to complete the cast, things are going fine.  However, once we add the ‘)’ we get:

image

Whoa – what happened to the other 3 calls?

I’m guessing there’s just some rewriting that R# does when things ‘complete’ (like the cast being added) and it just doesn’t take into account that it might be happening on more than 1 line at a time in 2010.

Here’s about the simplest version I could come up with – add the closing parens to multiple calls:

image

type ‘)’ and it kills N-1 of them:

image

R# 5.0 – inline method doesn’t understand ‘params’

Not really all that big a deal, but it hit me today, so I figured I’d do a quick little post+sshots and post the link in their forums.

So, start with a simple enough case:

image

Trying to inline that as-is doesn’t work with relatively obscure conflicts:

image

Now, this is caused by the no-args call, so just to get past that error and onto the next issue, we comment it out and then try to inline:

image

A couple of problems here:

  • The resulting code doesn’t compile, of course, since it’s trying to cast a string as an array (instead, it should have just created an inline array)
  • The multi-param calls lose data, since only the first param was kept around, the rest were thrown away

Adding in an intermediary call site changes things a little:

image

Inlining the inner (PrintAll) works fine since it’s inlining within a method that’s already got it passed as an array:

image

Inlining the outer fails, though, but different than our original case:

image

However, just like with the original, we can comment out the no-args version to get the inlining to work, with the same problems we saw in the original case (bad cast, loss of n-1 params)

image

resharper 5.0 bug? ‘put into using construct’ ignores user brace setting

This is about 50/50 whether it’s a bug or PEBKAC (the last ‘bug’ I mentioned on their forums was the latter), but here’s a post to doc it with sshots so I can just include a url in the forum instead of trying to figure out how to do images in their markup 🙂

So, my R# settings have everything at BSD-style braces (I was a K&R guy before my time @ MSFT, but now I’m too used to BSD style to bother switching).  In addition, the ‘braces in using’ option specifically shows that the resulting reformat (adding braces) uses BSD style (the style used in the reformat is determined by the ‘Other’ entry in the ‘Braces Layout’ section).

image

So, I have some normal IDisposable local variable and let R# add the using construct for me:

Cursor within the local var declaration (inside the ‘stream’ string)

image

hitting alt-enter to bring up the R# menu (the ‘pencil’ menu in this case)

image

Result:

image

I love what it did, EXCEPT that it added the using with K&R style braces instead of the BSD.

Now, certainly I could fix the braces myself or let R# do so when it I next do a ‘code cleanup’ and it fixes the bracing as part of that, but it’d be nice if it looked at my braces preference when it added the using 🙂

IMHO, the .net 4 client profile is more trouble than it’s worth

NOTE: I know I can (and likely will) edit the project template(s), but bear with me here.

Time and again I create a new project (like a console app) and I happen to want to do what I would consider to be reasonable to expect of a client profile – like, say, be a WCF client.

I end up using something like, say, WebHttpBinding or ChannelFactory, but it fails when I let ReSharper attempt to add the using+reference:

action:

image

result:

image

Ignoring the error message it gives (it’d be nice if ReSharper knew that the failed reference was due to the target framework not having the given lib and prompting to ‘elevate’ to full .net 4), I’ve got to figure out what’s going on when I hit this – I go check the references and sure enough, it’s broken:

image

Luckily around that time I remember having hit this before and it being caused by the WCF client bits not being in the .net 4 client profile, so I open the project properties and switch it over to the full framework:

image

The client profile (obviously not new in 4, see the 3.5 entry above) just seems like a stop-gap half-fix to me.  While I get that it’s easier said than done, it seems like you might as well just put the framework(s) on the web and let people choose either ‘prefetch the whole framework’ (like ‘full’ does now) or ‘fetch framework pieces as needed’ (perhaps what people paying per MB of download would choose), with a subset installed by default that includes enough to download others (obviously).  Why push the pain onto the developers?

I’d imagine ClickOnce (and Java Web Start before them) and Silverlight have gotten this kind of thing taken care of already.  We already have loading assemblies via http paths in the framework and it already includes caching IIRC, so the lower pieces are already in place.

Obviously, though, once you do this for the core framework, you can start to extend it out for others.  You can see the beginnings of this with something like the CDN-hosted javascript libraries (Microsoft and Google both do this). 

Like I said, though, I’m guessing this is more trouble than it’s worth for the product group (still questions like in or out of GAC, per-user or not, etc), but I really hate when a solution gets pushed out that causes more pain for developers.  Since I can’t do WCF clients with the ‘client profile’, I’m also pretty annoyed about that, too 🙂