Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Jetpac Refueled

This may just make a valid reason for me to get me an Xbox 360. Jetpac was one of the first games made for ZX Spectrum, and we used to play it for countless hours back in the eighties. It was released by Ultimate - Play The Game [makers of many legendary Spectrum games, including Atic Atac], and now, Rare, descendant of Ultimate, decided to re-release their first title, but with complete visual makeover and enhancements, worthy of contemporary console like Xbox 360.

Of course this is just a serious nostalgia trip... I'll probably never buy an Xbox, but I'm sure someday I'll be able to find someone who'd let me try this baby out, Retro mode included [see picture below] :) One thing will for sure be different - as Rare wrote on their Jetpac Refueled introduction page - I won't have to wait 5 minutes for it to load...

Jetpac Refueled - Retro mode

More info on Xbox Live Arcade

Alt-Tab flipping in Windows Vista

When running Windows Vista on a non-graphic-capable PC [not having at least DirectX 9 capable graphics processor], you lose the comfort of enjoying eye-candy features like Aero Glass, Flip 3D [Win-Tab switching] and graphically enhanced Windows Flip [Alt-Tab switching]...

What you can start to enjoy [even without having a capable graphics card], is the ability to switch to preferred application simply by clicking its icon while holding the Flip window open. Proves useful when having a lot of applications open at once. In pre-Vista Windows editions you'd have to tap the Tab key a few times to get desired application's tile selected and release the keys to set application focus.

Client Application Services and Membership provider

In previous VS "Orcas" post, we took a peek at Client Application Services, a part of .NET Framework 3.5 and the related System.Web.Extensions.dll. We also created a simple WCF LoginService, used for authenticating users against a Membership database, similar to what we're already using with ASP.NET 2.0.

Now, we're going to use that same login service, but in a different way. We won't be calling that service directly; instead, we're going to make our Login form call that service automatically, whenever our application would require user authentication. Sounds like what your current ASP.NET application is doing? Enter ClientFormsAuthenticationMembershipProvider...

The scenario is pretty much the same as with building web application. For starters, let's take our existing ClientService WCF project, and add a new Windows Forms project... I've called it ClientApplication. Before continuing, we'll have to add references to System.Web.dll and System.Web.Extensions.dll assemblies

Our first step is building a simple LoginForm to make user provide a username and a password. Adding the "Remember me" checkbox is optional, but you'd be missing out if you omitted it.

The important part in making a login form is implementing IClientFormsAuthenticationCredentialsProvider interface. This interface only cone method we'll have to implement - GetCredentials(). We'll use this method to return entered user credentials to the calling Membership provider:

public ClientFormsAuthenticationCredentials GetCredentials()
{
    ShowDialog();
    ClientFormsAuthenticationCredentials credentials = 
new ClientFormsAuthenticationCredentials(usernameBox.Text,
passwordBox.Text, rememberMeBox.Checked); return credentials; }

All that's left is to configure Membership provider to use and connect our LoginService and our Login form. Here's a snippet to include in our app.config file:

<membership defaultProvider="Default" >
  <providers>
    <add name="Default" 
       type="System.Web.ClientServices.Providers.
ClientFormsAuthenticationMembershipProvider,
System.Web.Extensions, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
credentialsProvider="ClientApplication.LoginForm,
ClientApplication"
serviceUri="http://localhost:51304/ClientService/LoginService.svc" /> </providers> </membership>

To use our Membership provider, simply call Membership.ValidateUser(string.Empty, string.Empty) from anywhere in the code to trigger provider asking for user credentials. When triggered, our Login form would be displayed and entered credentials would be validated against out Login service. After successful validation, application will continue to run in the context of validated user.

We've only just scratched the surface of what Client Application Services have to offer, there's a whole lot more goodies out there. More on that in next posts.

No more excuses...

... for not running Visual Studio 2005 on Windows Vista. Visual Studio 2005 Service Pack 1 Update for Windows Vista is available for download. Remember to uninstall the Beta before installing this release version.

And if you've installed SQL2005 SP2 already, here's a critical hotfix you may want to apply... This fix is however included in the refreshed SP2 package, so if you download it now (goes for downloads after 5th of March), you'll be fine.

VS &quot;Orcas&quot;: LoginService

ASP.NET 2.0 introduced Membership, Role and Profile providers for storing, validating and managing users' credentials and profiles to the web application development world. While these providers can quite easily be used in the same manner in a desktop application having the database store in the same domain, there is still a significant amount of code you have to write to make your application perform user credentials validation through a remote server (using, let's say, web services).

VS "Orcas" (or more precisely - .NET framework 3.5) brings us Client Application Services, which build up on existing functionality to allow us use these very same features (and more) in our desktop clients, and all communication between client and server would be provided by Windows Communication Foundation (WCF). There's a whole new assembly, dedicated to client services, called System.Web.Extensions, which we'll need when building our sample application. This sample will consist of a simple Login service, residing on a remote server and accessing it's local membership database, and a desktop client, connecting to this service through WCF.

Let's open Visual Studio "Orcas" and begin a new Web Site | WCF Service, called ClientService:

We're going to start with a Login service, which we're going to call whenever user attempts to log in our desktop client. First, we'll remove autogenerated App_Code\Service1.cs file from the project, rename Service1.svc to LoginService.cvs and add System.Web.Extensions.dll to this project's references [you'll find this dll in the c:\Windows\Microsoft.NET\Framework\v3.5.20209\ folder].

Next, edit LoginService.cvs file to make service reference a built-in LoginService class:

<%@ ServiceHost Language=C# Debug="true" Service="System.Web.ApplicationServices.LoginService" %>

We'll also edit your web.config to describe our service and enable ASP.NET compatibility:

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <services>
        <service name="System.Web.ApplicationServices.LoginService" 
behaviorConfiguration="LoginServiceBehavior"> <endpoint binding="basicHttpBinding" bindingConfiguration=""
name="LoginServiceEndPoint"
contract="System.Web.ApplicationServices.LoginService"/> <endpoint address="MEX" binding="mexHttpBinding"
bindingConfiguration="" name="MEX" bindingName="MEX"
contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="LoginServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> <system.web> <authentication mode="Forms" /> <compilation debug="true"> <assemblies> <add assembly="System.Core, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=B77A5C561934E089"
/> <add assembly="System.Web.Extensions, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"
/> </assemblies> </compilation> </system.web> <system.codedom> <compilers> <compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CSharp.CSharpCodeProvider,System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"
> </compiler> <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
type="Microsoft.VisualBasic.VBCodeProvider, System,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

compilerOptions="/optioninfer+"> </compiler> </compilers> </system.codedom> </configuration>

[just a quick note here: using wsHttpBinding instead of basicHttpBinding would make your WCF channel more secure]

The Login service is now complete, we're ready create our user/Membership database. Choose Website | ASP.NET configuration from the menu to invoke ASP.Net Web Application Administration tool, the same we're used to from building ASP.NET web sites in VS2005:

Click Security and wait a few seconds for membership database file to be created in your web project's App_Data folder. Then switch authentication type from Windows to Forms authentication and create a user or two:

OK, we're done with the server part; we're continuing with a simple test client...

We'll Add a new Windows Forms project to the solution, setting it as the StartUp project and reference our Login Service [Project | Add Service Reference]; in the "Add Service Reference" dialog, clicking on Find button will make our LoginService appear in the list of services:

After confirming service selection, a proxy class will be generated and we can start using our service.

To keep this sample simple, we'll use a simple form button to check our user's credentials, and here's the code:  

LoginServiceClient client = new LoginServiceClient();
if (client.ValidateUser("andrej", "p@ssw0rd", string.Empty))
{
    MessageBox.Show("Validated");
}
if (client.Login("andrej", "p@ssw0rd", string.Empty, true))
{
    MessageBox.Show("Login successful");
}
if (client.IsLoggedIn())
{
    MessageBox.Show("Logged in");
}

We're making three consecutive calls to our LoginService. With the first call, we're just validating users credentials. The second call tries to log in the application and the third call checks if the user is logged in. Note that when using persisting logins you'll have to allow cookies on your client side by modifying a part of your app.config:

...
<
binding name="LoginServiceEndPoint"
...
allowCookies="true"
...
>
...
</binding>
...

We've just set up a simple remote Login service, which allows our desktop client to use the same membership database we could already be using in our web applications. Coming up next: building up a login form, membership and role providers...

Smarter Client Development with Visual Studio &quot;Orcas&quot;

This series of posts will follow my exploration in forthcoming Visual Studio "Orcas" features, focusing on developing Smart(er) Clients, or, as the above title permits, smarter developing of (desktop) clients. I'll begin the series with my "Orcas" installation experience.

As mentioned, you can try out VS "Orcas" by mounting a Virtual PC image or by a separate installation. Choosing VPC, you get Windows 2003, together with VS2005, SQL2005 and VS 9.0 ("Orcas") already installed. On the other hand, separate installer will install "Orcas" bits only. But before you do that, just make sure you don't have any previous "Orcas" CTPs installed on your PC or you'll get some weird installer errors, complaining on some files being missing from your temp folder. To help you with uninstalling unwanted CTP leftovers, see this page; in my case, I had to manually delete the "Program Files\Microsoft Visual Studio 9.0" folder for a successful install.

To continue, there are some quite serious issues involved with the product installation, some of which are closely related to side-by-side installation with VS2005 and/or SQL2005 (see numbers I./7., II./19. and II./20. in Visual Studio Code Name "Orcas" Release Notes). Although the same release notes suggest using the March CTP from a VPC image, this doesn't seem to fix it, because both VS2005 and SQL2005 are co-installed with "Orcas", therefore suffering from this same issue. It looks like what we really need is a fresh, VS2005-less machine...

One of my next steps will include setting up a separate Windows Vista VPC with clean "Orcas" installation and see how it goes from there. But before that, we'll going to look into some new client features "Orcas" has in store for us... Stay tuned!