Dennis van der Stelt

The most votes generally drown out the best votes

Community

News

  • Meet me at PDC08

Email Notifications

I read...

I Use...

Tags

Recent Posts

Archives

November 2006 - Posts

WCF Part 6 : Address

We'll return once again to the WCF ABC and in this part we'll examine what we can do with the address of our service. There are many options on how to specify the address of your service, especially when you start combining options. But I'll discuss the three main options. Don't be scared by the size of this article, it's easy to understand. :-)

Explicitly
As seen in part 3 about configuration, we configured the address of our service explicitly in the address attribute of our service's endpoints; one for our service itself and one for metadata. What we haven't done is setup an endpoint for WSDL discovery. If we want to enable http discovery, we need to set this up at the serviceMetadata behavior. Because we're not using relative addresses, we need to set it explicitly as well.

<serviceBehaviors>

  <behavior name="MyServiceBehavior">

    <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080/Hello/" />

  </behavior>

</serviceBehaviors>

Now the wsdl is immediately accessible from the root of our service or by adding /?wsdl to the url.

Relative (preferred option)
You're better of using relative addresses though, for various reasons. One of them is administration, as all addresses aren't scattered throughout your config and application. To support relative addresses, the WCF team introduced base addresses to the configuration, after a lot of requests from users. Using a base address, you'd get the following.

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MyServiceBehavior">
        <serviceMetadata httpGetEnabled="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <services>
    <service behaviorConfiguration="MyServiceBehavior" name="Hello">
      <endpoint
        address="Hello"
        binding="basicHttpBinding"
        contract="IHello" />
      <endpoint address="MEX" binding="mexHttpBinding" contract="IMetadataExchange" />
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost:8080/"/>
        </baseAddresses>
      </host>
    </service>
  </services>
</system.serviceModel>

As you can see, the host node was added with one base address. Next article we'll introduce other bindings and have multiple base addresses. Both the service endpoint, the MEX endpoint and the WSDL document (enabled with httpGetEnabled) don't need an address anymore. Their addresses are respectively:

  • http://localhost:8080/Hello/
  • http://localhost:8080/MEX/
  • http://localhost:8080/?wsdl

Programmatically
This is the option that was used in the past, before the base address was introduced. When creating a ServiceHost object, you can pass in the base addresses for it. Of course you can do this hardcoded, but we just don't do that anymore in 2006 as we all know it'd take a recompile and redeploy to change the address. So we grab it from our configuration file. Here's the config.

<appSettings>
  <add key="httpBindingAddress" value="http://localhost:8080/" />
</appSettings>

And then we can use it in our code and pass it into our ServiceHost constructor, like this.

Type type = typeof(Hello);
 
string httpBindingAddress = ConfigurationManager.AppSettings["httpBindingAddress"];
Uri[] baseAddresses = new Uri[] { new Uri(httpBindingAddress) };
 
using (ServiceHost host = new ServiceHost(type))
{
  host.Open();
}

Multiple base addresses
Although we're not going to talk about bindings and need multiple addresses, we are talking about addresses, so I want to show you how this is done. First, we'll use the programmatic version. Of course our config file holds these addresses under different keys. The code would be this.

string httpBindingAddress = ConfigurationManager.AppSettings["httpBindingAddress"];
string nettcpBindingAddress = ConfigurationManager.AppSettings["nettcpBindingAddress"];
 
Uri httpUri = new Uri(httpBindingAddress);
Uri nettcpUri = new Uri(nettcpBindingAddress);
 
Uri[] baseAddresses = new Uri[] { httpUri, nettcpUri };
 
using (ServiceHost host = new ServiceHost(type, baseAddresses))
{

So we can do this in config too? Of course. In the relative addresses method, the code doesn't have to change. Isn't that just great? Look at the changes between the configuration below and the one from the relative paragraph. And please note, that the MEX endpoint has information for both http and net-tcp endpoints.

<service behaviorConfiguration="MyServiceBehavior" name="Hello">
  <endpoint
    address="httpHello"
    binding="basicHttpBinding"
    contract="IHello" />
  <endpoint
    address="nettcpHello"
    binding="netTcpBinding"
    contract="IHello" />
  <endpoint address="MEX" binding="mexHttpBinding" contract="IMetadataExchange" />
 
  <host>
    <baseAddresses>
      <add baseAddress="http://localhost:8080/"/>
      <add baseAddress="net.tcp://localhost:8090/"/>
    </baseAddresses>
  </host>
 
</service>

[Go to the WCF series article index]

IIS7 and Url Rewriting

IMPORTANT UPDATE
I found out where the <module> tag belongs! :)

I was running in Classic .NET AppPool, when switching to the DefaultAppPool in IIS7 I could use the <modules> section. So the new way to use HttpModules for UrlRewriting is:

<modules runAllManagedModulesForAllRequests="true" >
  <add name="RedirectEngine" type="RedirectEngine.Rewrite, RedirectEngine" preCondition="managedHandler" />
</modules>
<validation validateIntegratedModeConfiguration="false" />

No idea what the last tag does, but IIS7 placed it there, so I hope it does any good ;-)

 

Continue with (old) article...

I have this website that needs to pump out some information to another application, just plain old xml. The problem is that this application was originally calling some weird app that was accessed through these kind of urls:

  • http://myserver/folder/giveme?id=120
  • http://myserver/folder/iwanttoknow?id=120&more=1

So my solution was to place a backslash, so you'd get http://myserver/folder/giveme/?id=120. That way, it would be redirected to default.aspx and handle the request. Unfortunately, not an option, as the url was created by the calling application, based on just the domain. So after /myserver/ I had no control over the url it looked at.

My alternative was url rewriting. When there's a request to some file, check the last part of the folder requested and redirect it to the right folder with a nice default.aspx in it. Until I ran into IIS7.

IIS7
The problem here is, that the request to non existing files don't pass my HttpModule anymore! I just get a 404 and no breakpoint inside my code gets hit. In IIS6 every incoming call is forwarded to my HttpModule. I kept on seeing requests for favicon.ico for example. Not in IIS7 though.

Don't ask me what I tried to get it working. I looked at Scott Guthrie's blog, but couldn't find anything useful. Except this item, where Scott says you'll have to configure IIS7 to make it work. Sure, thanks Scott, but how?! I also found this forum thread on iis.net but have no idea where the <modules> tag should go.

So what's my solution? I added a handler to IIS, which seems possible inside your web.config since IIS7. I added the following:

    <system.webServer>
        <handlers>
            <add name="MyFiles" path="*" verb="GET" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="File" />
        </handlers>
    </system.webServer>
</configuration>

So now every unknown file extension will be redirected to the ASP.NET Isapi module. Meaning it'll go through my HttpModule and I can redirect the request. This isn't all though, it still won't transfer calls to me if there's no file. So for every request that's made, you'll have to figure out what the file should be and place one in the folder. My files are, based on my demo urls in this article, "giveme" and "iwanttoknow".

Remember, this is not a solution! It just plain sucks! I want it to work like in IIS6. However I need it to work right now on IIS7 as well, and fast, so I can finish this app. I'd like to hear if people know how to get it working without the handler and empty files. So leave a comment or contact me if you know.

Technorati tags: ,
Display WCF host details; code snippet

Because I'm doing presentations, demos and the WCF article series, I host a lot of WCF services inside a console application. Console applications are great for demonstrating something really quickly. When hosting a WCF service in a console application, you require a pause so that your client applications can use the service. Preferably a user closes the service. I know Michele Leroux Bustamante was using some code to display basic information about the services and have used this to create myself a Visual Studio 2005 C# snippet. It shows the base addresses as well as dispatchers listening with their binding.

When you place the snippet into the appropriate folder (depends on which version of Windows you're using ;) you can press either CTRL-K, CTRL-X and select it manually, or you use the intellisense version and type "host" into Visual Studio 2005 and press the TAB key twice. You can then supply the name of your host object and run your service.

Unfortunately C# cannot add namespaces, so the snippet presumes you have System.ServiceModel referenced.

Here's the code, place save it under "host.snippet".

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Display WCF ServiceHost details.</Title>
      <Shortcut>host</Shortcut>
      <Description>Code snippet for displaying WCF ServiceHost details in a console application.</Description>
      <Author>Dennis van der Stelt</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <References>
        <Reference>
          <Assembly>System.ServiceModel</Assembly>
        </Reference>
      </References>
      <Declarations>
        <Literal>
          <ID>host</ID>
          <ToolTip>The host object</ToolTip>
          <Default>host</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[Console.WriteLine("Number of base addresses : {0}", $host$.BaseAddresses.Count);
        foreach (Uri uri in $host$.BaseAddresses)
        {
          Console.WriteLine("\t{0}", uri.ToString());
        }
 
        Console.WriteLine();
        Console.WriteLine("Number of dispatchers listening : {0}", $host$.ChannelDispatchers.Count);
        foreach (System.ServiceModel.Dispatcher.ChannelDispatcher dispatcher in $host$.ChannelDispatchers)
        {
          Console.WriteLine("\t{0}, {1}", dispatcher.Listener.Uri.ToString(), dispatcher.BindingName);
        }
 
        Console.WriteLine();
        Console.WriteLine("Press <ENTER> to terminate Host");
        Console.ReadLine();]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>
Running Vista; Part 3

SQL Server 2005 problem solved. The ISO's I used were probably corrupted. I installed from cd and everything installed like a charm. I'm running SQL Server 2005 Developer Edition without problems now.

Vista isn't the most stable OS I've had so far. I keep running into small problems.

  • C++ Runtime error when starting Internet Explorer.
    For some reason, this sometimes occurs. I start IE7 and a popup appears that the C++ runtime ran into problems. I have to reboot for it to disappear.

  • Complete lockups
    Internet Explorer sometimes hangs and completely locks up the OS. They had this fixed in WinXP with some service pack by separating the OS and IE a bit more. If I'm not mistaken, because of some EU demand. I liked the update very much!
  • Another weird problem I had recently was some .dll it could not load. I've forgotten what .dll it was, but I think it had something to do with the graphics system inside Vista. I don't mind dll's not loading, but that wasn't the only thing. The taskmanager gave the exact same error and would not load anymore!!! Now that sucked! Together with the BSOD because of my USB Drive, the complete lockups and this problem make me wonder why Vista isn't more stable!
  • For some reason IIS7 isn't working as it should. The Sidebar widget to report on IIS activity doesn't work and also IIS6 compatibility doesn't work either. I still can't get it to work with Visual Studio 2005 web development.
  • Another small glitch is that full-screen videos are a lot slower than in WinXP. No idea why, probably because the heavy graphics system kicks in.

So no major problems anymore. I'm working at least 8 hours a day with Visual Studio 2005, SQL Server 2005 and other tools to enhance my development experience. (Yes Alex, this includes NUnit, TestDriven.NET, NCover, etc ;-)

However, what are my positive experiences? Only on the graphical side. I absolutely LOVE the new graphics system. Watching a video, hovering over the video in the taskbar and seeing a 2nd window playing the video and then pressing alt-tab to see a third window playing the video just gives me warm feelings. I love those kind of things. So when that's working, it really makes me wonder why in full-screen the video is so much slower.

I'm keeping my Vista though, love it! And love to be one of the first.

Secure databases : SQL Server vs. Oracle

Via Steve Eichert I came across an article about database security. It's based on security flaws that have been reported over the years by external security researchers. Only flaws affecting the database servers itself have been considered, so Oracle Application Server has not been included for example. The conclusion is clear

The conclusion is clear – if security robustness and a high degree of assurance are concerns when looking to purchase database server software – given these results one should not be looking at Oracle as a serious contender.

When you look at the graphs, Oracle was pretty secure in the past, but since 2005 the number of security flaws has increased immensely. When we look at the previous SQL Server versions, less security flaws were reported over the years. When we look at SQL Server 2005, it hasn't had a single security flaw reported since launch.

Technorati tags: ,
Running Vista; Part 2

So I'm still running Vista and guess what... I got my first BSOD this morning! I can't remember the time I had this with WinXP.

New default in Vista is sleep, instead of shutting down. So when you press your pow... *** ... power button, you computer ends up in sleep modus. This means you boot up faster and memory is kept alive. This means your laptop consumes battery power, but only so little that it can stay this way for days. So when my laptop went to sleep yesterday, it had a USB harddrive attached. This morning I booted up and executed explorer. Immediate blue screen in usbstor.sys. Guess what the problem was! ;-)

SQL Server 2005 Dev Edition still isn't installed, I gave up. I hope Microsoft will respond to my plea. In the meantime, I've installed SQL Express SP2 enabled and that went flawlessly.

Outlook Web Access still doesn't work, even though the latest service pack was installed. I'll have to look into this further.

Things I've noticed so far:

  1. The sidebar is really great, better than any alternative I've used in the past. One thing though, when Windows+D (to desktop) the sidebar is gone. That's not what I want!!! Can't change it.
  2. You can alt-tab to the desktop. How, how can I turn this off? What's the Windows+D key for anyway!?
  3. Alt tabbing through applications works great, but when you're really fast with it, it's a bit slower than WinXP.
  4. Windows+Tab isn't useful, much too slow. Perhaps if the animation from normal screen to 3D view was removed, and you started in 3D view immediately, it'd be useable.
  5. Windows Live Messenger windows aren't shown in the preview windows. You can view preview windows while alt-tabbing and when hovering over your taskbar. Why's it not showing?
  6. IE7 specific : You can't open a new tab based on a currently open tab, this sucks.
  7. IE7 specific : I used to drag the address-bar icon to the address bar, to refresh the page without postback, as explained to me by Alex Thissen. You have to drag it to the tab now, which could be handy. Problem is, you can't drag it to any of the other tab-pages. How weird is that? Either fix it so I can drag my link to the address bar, or so that I can drag it to any of the tabs (which I would prefer).
  8. This has been said before, but it sucks you can't create .NET sidebar applications. I would've probably created some myself. Now I don't care to bother.

I'll keep you posted on my problems.

*** Shit, a small window appeared when installing an application, and while typing I pressed space and the window disappeared again. I hate that! Perhaps I shouldn't use default buttons anymore myself.

Running Vista; Redmond, we have a problem

So I'm running Windows Vista. And although it's running very smoothly itself, there are some problems.

  1. SQL Server 2005 won't install
    This is the weirdest one and I have no idea how to solve it. The server/service itself has installed, but client tools (Management Studio) doesn't. And that's currently the application I need most.
  2. Outlook Webmail Access uses a DHTML Editor that's not installed with Windows Vista because of security reasons. I can read, but not write and email. There is a solution (download) for it, but that only installs the editor for applications, not the browser enabled version. The only solution is to install the latest Exchange patch so the DHTML Editor isn't neccesary anymore. Luckely we have VPN as well, so I can still write email.
  3. Visual Studio 2005

I already knew it had some issues, but I just had to try and see for myself. First things I've noticed are that VS2005 can't attach itself automatically to the web server anymore. I haven't tried IIS and/or WinForms yet.

Another problem I have is that Vista has IPv6 support. This means that Dns.GetHostEntry suddenly also returns hexadecimal email addresses. But I was building up some links for an intranet website/application using ip addresses. Win2003 can't handle the IPv6 ip addresses! ;-)

Luckely I found some code on the internet that should be the solution, I guess.

    private IPAddress GetIPAddress(string dataSource, System.Net.Sockets.AddressFamily addressFamily)
    {
      try
      {
        IPAddress[] addresses = Dns.GetHostEntry(dataSource).AddressList;
 
        // Try to avoid problems with IPV6 addresses
        foreach (IPAddress address in addresses)
        {
          if (address.AddressFamily == addressFamily)
          {
            return address;
          }
        }
 
        return addresses[0];
      }
      catch (Exception ex)
      {
        // If it's not possible to get the list of IP adress associated to 
        // the Data Source we try to check if Data Source is already an IP Address
        // and return it
        try
        {
          return IPAddress.Parse(dataSource);
        }
        catch
        {
          // In this case we want to rethrow the first exception
          throw ex;
        }
      }
    }

You can request your own ip address should be retrieved using the following line:

GetIPAddress(Dns.GetHostName(), System.Net.Sockets.AddressFamily.InterNetwork );

I'm currently connected to the internet and our company's VPN, so I have 6 ip addresses in my AddressList. The first IPv4 address return is indeed what I need and I can only assume this also works in production. I'm still unsure how to write a test* for this though.

*= I didn't write unit test, because else people might start complaining. ;-)

Downloading Vista RTM

Only 29 seconds left! I'm downloading Vista off of MSDN right now at a speedy 2.6 megs a second.

Eat your heart out, Scott!

WCF Part 5 : Consuming the service

Last time we generated the client and configuration file. Whereas in the asmx world we had a proxy class, the WCF team renamed this in the June CTP to client. For us to use the generated files, we need a new console application and add the files. Don't forget to add the System.ServiceModel reference to the project. Once this is done, it should compile without errors.

We'll have to create an instance of the client. At that point, the application configuration on the client will be read. However, there won't be a connection until the first call has been made. After creating the instance, we can call the HelloWorld operation. Notice that the HelloComputer operation isn't exposed, as we didn't apply the OperationContractAttribute in the interface. Besides the generated files, not much code is needed to execute the call.

    1 static void Main(string[] args)
    2 {
    3   Console.WriteLine("Press any key when the service is available...");
    4   Console.ReadKey();
    5 
    6   HelloClient client = new HelloClient();
    7 
    8   string msg = client.HelloWorld();
    9 
   10   Console.WriteLine("The message is : {0}", msg);
   11   Console.WriteLine("Press any key to quit...");
   12   Console.ReadKey();
   13 }

On line 6 the instance is created, on line 8 we call the service. Line 10 shows the message in the console window. Notice line 3 and 4. When we start (or execute) both assemblies at the same time, we need to be able to wait and allow the service to get up and running.

There are two methods to execute the assemblies. You can right-click a project in Visual Studio 2005, choose Debug and Start new instance. Or you can right-click the solution, choose Set StartUp Projects... and select the radiobutton Multiple startup projects. Then specify 'Start' for both projects. After hitting the F5 key, both projects will be started at the same time.

Consumer configuration
You can examine the configuration of the consumer, in our case our console application that's calling the service. You'll see a lot of info on the basicHttpBinding, but that's not really important right now. Just stuff on timeouts, message encoding, etc. that's all default. What is (kind of) important however, is everything in the client element.

<client>
    <endpoint address="http://localhost:8080/HelloService/" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IHello" contract="IHello"
        name="BasicHttpBinding_IHello" />
</client>

Again you'll notice the WCF ABC, address, binding and contract. All this has been imported by the Service Utility (svcutil.exe) and is now inside the client class as well.

We've setup our first (have we? ;-) running service and client application and we're talking in text/xml over http with each other. We're running this on the same computer, but you could place either one of these applications on the other side of the world and wouldn't notice a difference, but perhaps some delay because of the distance.

You can download the complete solution here, to see how I've set everything up. Before we take further steps into the world of Windows Communication Foundation and get beyond the WCF ABC, we'll examine what we've done exactly.

Update : Be sure to have the WCF/WF extensions installed! You don't need the >1GB SDK installed.

[Go to the WCF series article index]

Refactor! Pro goodness : Safe rename

Renames a non-private method or property in the class in a manner that does not break code in other assemblies which is dependent upon the old name.

Do I need say more? Perhaps a picture that says more than a thousand words... I wanted to rename my WriteDocumentElements method and pressed ctrl-~ in Visual Studio 2005 with Refactor! Pro installed.

 

Technorati tags:
Refactor it!

Now this is a great initiative! Billy McCafferty is doing a weekly contest where he uploads a Visual Studio 2005 solution of a C# project with a specific code smell. You must refactor the solution so that the code smell is removed and so it still passes the supplied unit tests. Winners are randomly drawn by his two year old daughter, because he doesn't trust the randomness of Math.Random. :-) I think the initiative is cool because people will hopefully learn what refactorings are about. I hope he'll post some of the best solutions and that the winner will get a long review post where Billy will explain all the refactorings that took place.

Refactoring has been widely adopted as a vital technique for producing high quality software.  It is important that we each embrace this practice into our development work.  This contest will serve to present an overview of common smells found within code and discuss techniques to correct those smells for creating better software.

The first challenge is already online for a few days. Read info on Refactor It! and the first challenge here. I've taken a look at the code and there is are some beautiful codesmells in there. This is code that could've been extracted from a lot of applications that are currently in production, maintained by developers who have to study the code to understand it. The refactorings should make a lot of sense in there. This could also be a great way to learn Refactor! Pro by DevExpress, the tool to use for this kind of stuff.

Oh, Alex, sorry mate, but the tests are written for NUnit. Of course I immediately ran NCover over it and NCoverExplorer produced this result:

There's one line of code that throws an error when you pass in a null value into the method. Meaning this probably wasn't written using Test-Driven Development. Not the worst case, but it would be nice to show people how good the tests could be when TDD was used. Besides that, I again have to say I love the initiative and will keep an eye out for the results.

Technorati tags: , ,
Finding available callback tcp port for a WCF chat client

While having some fun writing a WCF chat application, I was having some troubles.

I was using duplex communication over http, using the WsDualHttpBinding. The client needs to setup a callback channel for the service to... well, call back actually. Hence the name, I guess ;-) Anyway, by default it wants to create this channel on port 80, which wasn't possible because IIS is already listening on that port. For that you need to specify the ClientbaseAddress on your binding.

DuplexChannelFactory<IChatService> dcf = new DuplexChannelFactory<IChatService>(client, "ChatService");
Uri uri = new Uri(@"http://localhost:8000/callbackchannel");
((WSDualHttpBinding)dcf.Endpoint.Binding).ClientBaseAddress = uri;

Now the callback channel is on port 8000. But, you might want to start multiple clients to test your service. So you need to know what port isn't taken yet. I wasn't the first to ask this question, but either I'm really lousy in searching Google, or nobody has blogged a complete answer yet. Either way, here's what I used.

int selectedPort = 8000;
bool goodPort = false;
IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
//
while (!goodPort)
{
 
  IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, selectedPort);
  TcpListener list = new TcpListener(ipLocalEndPoint);
  try
  {
    list.Start();
    goodPort = true;
    list.Stop();
  }
  catch
  {
    selectedPort++;
  }
}

There you go, now you know as well.

Update : Was having some problems with CopySourceAsHtml after changing some settings. Should work now.

Bitslapping contest : LX vs Compile on Test integration in VS2005, part 2 response

Well, it seems Alex took things seriously and is slapping his bit-stick around. Thinks he can just slap me around and walk away with a smile, huh? Well, I'm not done with round 1 Alex.

Round 1

  1. Reflector integration
    Thank you for the point, Alex.
    +1 Dennis
  2. Code coverage
    Alex should've checked out the tools I'm using before he wants to slap me around. When you just take a look at this animated gif, I don't need to explain myself any further. However, I will, just because I know Alex likes that slap in the face. Not sure if he likes 10 slaps though
    1. Instrument any assembly? Of course NCover does that!
    2. Watch code with color highlighting? NCoverExplorer does that as well!
    3. Code coverage results? Ha! Alex, where are your status-bars? I can only see numbers. How about that quick-scan through hundreds of methods?
    4. Oh, don't forget the code coverage reports based on number of visits? And coverage based on sequence points? And the satisfactory threshold you can set!
    5. Alex, can you generate MSBuild and Nant scripts with the click of a button, so we can include these in our daily build scripts and create separate reports for those?
    6. A feature I also love is that I can look at my code coverage in NCoverExplorer, while continue to develop in my favorite; not having to rerun my code coverage every time just saves me so much time.
    7. Options are there to exclude assemblies, namespaces or classes from the report.
    8. For all you complete junkies out there, NCoverExplorer supports regular expressions to create complex queries in the coverage exclusions dialog.
    9. NCoverExplorer also supports saving in both XML and HTML, where the native html can be directly attached to e-mails to send to your colleagues, who just like to look at your great coverage report. Have I mentioned status-bars yet?
    10. And last but not least, can I get VS2005 code coverage with Visual Studio Express?

      Oooh, I so love my NCover and NCoverExplorer.
      This cannot be anything else than a point for me.
      +1 Dennis
  3. Repeat Test Run
    Alex has got me there with his arbitrary set of tests.
    +1 Alex
  4. Test with .NET 1.1 from within Visual Studio 2005
    +1 Dennis. No comments.
  5. Pluggable unit testing frameworks
    Irrelevant I think not. Mike Glaser did indeed mention Data Driven unit tests in Visual Studio 2005, and that's where MBUnit comes in, specialized in data driven unit tests. However, I'll accept no points as we both support data driven unit tests. I'll have to come up with a winner to get a point.
    No points
  6. TypeMock.NET integration
    Irrelevant? Again I think not! How could you use unit testing without a mocking framework? This is part of my testing framework. Alex decided to not make it count, because Visual Studio 2005 doesn't support this or any other mocking framework. But because VS2005 doesn't support it, doesn't make it irrelevant.
    But again, I'm not the worst guy in the world
    No points

So the score isn't a tie now, it's 3 for me and 1 for Alex. However...

...Alex comes back with a part 2.

Round 2

  1. Three frameworks for testing? If I can't bring along my mocking framework, you can't bring along your load testing. :-)
    However, I can't beat his web testing framework. I could bring in NUnitAsp but that can't be compared with VS2005 web testing
    +1 Alex
  2. Attribute goodness
    That's a matter of opinion on what attributes you like best. Of course I can guess why they brought in the timeout attribute; VS2005 unit testing is so slow, you don't want it to run forever. NUnit doesn't need a timeout attribute! :-) NUnit has Platform, Category, Explicit and other attributes I like far better than the VS2005 attributes Alex mentions.
    No points
  3. Integration with Team Foundation Server
    Again the rule applies that this is about unit testing frameworks. You can't bend the rules that way Alex, we're not inside The Matrix.
    No points

Still no tie. Alex (LX) has 2 points, I have 3. And the score would be even uglier if I wasn't that friendly the first round with bullets 5 and 6. Only because I was friendly. Again I say "However..."

Round 3

...I'll come back with a response. To be continued... :-)

Community Server newMediaObject

I wanted to see if the newMediaObject module, offered by the Community Server team, had benefits over my current implementation. Although I still have to figure out why, the implementation we had running kept creating copies of the media objects when re-publishing something. After updating, this doesn't happen anymore, something that can save me some megabytes.

I did make a change though. We're using George J. Capnias' FreeTextBox wrapper and it uses the fullname as storage location. That's why I've changed inside the original version. You can download it here.

However, if you'd like to make the changes yourself or change it to something completely else, you can do it yourself. Create a local copy of your community and place the .ashx file inside the /blogs/ directory and open it with Visual Studio and set a breakpoint at the first line in the MetaWeblog2.MediaObjectInfo method. Then from the VS2005 menu choose Debug -> Attach to process... Choose the aspnet_wp.exe process. Open Windows Live Writer, create a new post, insert an image and publish it. Visual Studio 2005 should pick up the request and start debugging.

The code I changed is merely the lines below the commented out lines.

if (mediaObject.bits != null && !Globals.IsNullorEmpty(mediaObject.name))
{
  //AddFile(weblog.ApplicationKey, new MemoryStream(mediaObject.bits), mediaObject.bits.Length, mediaObject.name);
  AddFile(username, new MemoryStream(mediaObject.bits), mediaObject.bits.Length, mediaObject.name);
 
  MediaObjectInfo info = new MediaObjectInfo();
  //info.url = Globals.FullPath(FileStorageUrl(weblog.ApplicationKey, mediaObject.name));
  info.url = Globals.FullPath(FileStorageUrl(username, mediaObject.name));
  return info;
}
WCF Part 4 : Make your service visible through metadata

Last time we saw how we could create an instance of our service by hosting it using some configuration in our app.config. We still need to have it exposed using metadata though. We'll do this by adding an endpoint that exposed this, using our WCF ABC again. This endpoint is called a MEX endpoint, from Metadata EXchange.

For this we don't have to create any code, just configuration again. Open the Service Configuration Editor again on our app.config. Open the folder "Advanced", then "Service Behaviors" and choose to add a new service behavior. We'll change the name NewBehavior to HelloServiceBehavior. Now click the Add button and select the 'ServiceMetadata' option.

Our added service behavior for the MEX endpoint.

Now we'll configure our new behavior in and endpoint. Select your service again in the tree. This is something you'll probably forget a lot in the future, but you'll have to bind the just configured behavior to your service. You should be able to select it from the list in the BehaviorConfiguration property on your service.

Now let's actually add our MEX endpoint. Select the "Endpoints" folder under our service and right-click it, then choose to add a new endpoint. Set the address to http://localhost:8080/HelloService/MEX/, select for binding the "mexHttpBinding" and for contract fill in "IMetadataExchange". Now save, exit the configuration editor and you should have the following configuration.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="HelloServiceBehavior">
                    <serviceMetadata />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="HelloServiceBehavior" name="Classa.Wcf.Samples.Hello">
                <endpoint address="http://localhost:8080/HelloService/" binding="basicHttpBinding"
                    bindingConfiguration="" contract="Classa.Wcf.Samples.IHello" />
                <endpoint address="http://localhost:8080/HelloService/MEX/" binding="mexHttpBinding" bindingConfiguration=""
                    contract="IMetadataExchange" />
            </service>
        </services>
    </system.serviceModel>
</configuration>

Run your service with F5. You'll notice no difference, but now you can create a proxy with the service util. Open the Visual Studio Command Prompt (in your start menu under Visual Studio 2005/Visual Studio Tools) and execute the following command:

svcutil.exe /o:client.cs /config:app.config http://localhost:8080/HelloService/MEX/

If you're interested, take a look at the generated files. Especially the generated app.config, which should contain an ABC reference to your service.

[Go to the WCF series article index]

More Posts Next page »