Monday, November 30, 2009

WCF Security

The Thanksgiving break was nice ... pretty much spent all my time (other than family time) studying from my WCF book and reading WCF articles online.


Starting to focus on Security in WCF.

Security in WCF is classified as either Transport-level Security or Message-level Security.

Transport-level Security is known as point-to-point security (also termed "hop-to-hop security" on Microsoft sites), and secures data as it is transferred across the network. It is vulnerable to messages traveling through intermediary, unsecured points between the sender and receiver of the Message.

Message-level Security is known as end-to-end security, and involves securing the message itself, ensuring message privacy and integrity, regardless of the path taken from sender to receiver.

There are 3 Security modes:
  1. Transport
  2. Message
  3. TransportWithMessageCredential
These are described on this MSDN article about Programming WCF Security.

Once the security mode has been selected, the developer needs to select a Client Credential Type. The clientCredentialType is an attribute on the transport or message tag under security in the binding. There are different clientCredentialTypes available for transport or message.

Here is an MSDN article on Selecting a Credential Type.

The final step is to set the Client Credential Values.

Sunday, November 29, 2009

WCF Hosting

There are several options available when choosing a Service Host for a WCF Service. These include:
  • IIS
  • WAS (Windows Process Activation Services), built into Vista and Windows Server 2008
  • Windows Service (starts and stops with the OS)
The selection of a Service Host does not have any impact on the development process of the WCF Service itself.

Service hosts must do the following:
  1. Instantiate System.ServiceModel.ServiceHost
  2. Add endpoints to the host
  3. Start the host listening
Several notes about host selection:

  • WAS enables hosting of services that do not rely upon HTTP.
  • When hosting in IIS, must choose a binding that specifies HTTP as the transport, such as basicHttpBinding, wsHttpBinding, wsDualHttpBinding. Choosing a binding based on a different transport causes an error.
WCF supports an ASP.NET Compatibility mode, which allows ASP.NET to provide the hosting environment (and thus the service can get to ASP.NET implicit objects and methods). In order to enable compatibility mode, two things must be done:
  1. aspNetCompatibilityEnabled attribute of must be set to true
  2. AspNetCompatibilityRequirements must be set to Allowed at Service Behavior level.

Friday, November 27, 2009

WCF Study Resources

Links I found while studying:

WCF Bindings

Bindings are pre-packaged channel stacks. WCF provides 12 bindings:

  • basicHttpBinding - WS-I Basic Profile, and ASMX Web Services
  • wsHttpBinding - advanced WS-* Web Services, WS-Security, WS-Transactions
  • wsDualHttpBinding - Duplex Web Services
  • webHttpBinding - REST / POX-based Web Services using XML and JSON.
  • netTcpBinding - communication between two .NET systems
  • netNamedPipeBinding - Communication between one or more .NET Systems.
  • netMsmqBinding - Asynch communication via MSMQ
  • netPeerTcpBinding - P2P networking applications
  • msmqIntegrationBinding - Sending and receiving messages via MSMQ
  • wsFederationHttpBinding - Web Services that use Federated Identity
  • ws2007HttpBinding - same as wsHttpBinding, with enhanced support for changes in 2007
  • ws2007FederationHttpBinding - same as wsFederationHttpBinding, with enhanced support for changes in 2007
Bindings that start with "net" are used to support WCF between .NET applications. Bindings that start with "ws" are used to support interoperability with non .NET applications.

netNamedPipeBinding is for binary, local machine communication only (and consequently has the highest performance metrics). The address will take the following form: net.pipe://localhost/{service}.

netTcpBinding addresses will take the format: net.tcp://{hostname}.

netMsmqBinding addresses will take the form: net.msmq://{hostname}/[private/public]/{queueName}. The default port is 1801 and cannot be changed.

WCF Channels

WCF Applications communicate by sending messages across channels.

There are two types of channels: Transport Channels and Protocol Channels. Transport channels sit at the lowest layer and provide the actual transport for messages. Protocol channels provide security, transactions, sessions, and message reliability.

Channels are layered upon one another, to create a channel stack. Bindings represent channel stack configurations, and simply the process of creating and referencing channel stacks.

The 3 communication patterns:
  • One-way
  • Request-Response
  • Duplex
are supported by 10 different channel shapes. There are actually 5 different shapes, each with 2 versions (one that supports sessions, and one that does not. Here are the 5 shapes:
  • IOutputChannel (IOutputSessionChannel). Supports one-way communication.
  • IInputChannel (IInputSessionChannel). Supports one-way communication.
  • IDuplexChannel (IDuplexSessionChannel). Supports duplex communication.
  • IRequestChannel (IRequestSessionChannel). Supports request-response communication.
  • IResponseChannel (IResponseSessionChannel). Supports request-response communication.
Channel listeners and channel factories will listen for messages.

Channel listeners can be closed without closing down the channel on which they were listening.

Channel factories are responsible for closing down their channels.

ICommunication object is the basis of all communication objects in WCF, which includes channels, channel factories, and channel listeners. Communication objects go through states: Created, Opening, Opened, Closing, Closed, and Faulted. Events are thrown when the Communication object transitions between these states.

Thursday, November 26, 2009

WCF Contracts

3 Types of WCF Contracts:


  1. Service contracts: Maps class methods to WSDL services.

  2. Data contracts: Maps .NET classes to XML Schemas.

  3. Message contracts: Maps .NET classes to SOAP messages

I read through the section entitled "Service Contracts" and the message exchanges described follow standard communication patterns:

  • Request-Response (Synchronous and Asynchronous)

  • One-way

  • Duplex communication

I started working with the [DataContract] and [DataMember] attributes, which handle the manner in which model classes are mapped to the XSD ComplexType.

Very cool stuff.

Here's some sample code I wrote:



using System;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace WinCommFoundation
{
[DataContract (Namespace="http://philiptenn.com/wcf", Name="PersonComplexType")]
public class Person
{
[DataMember(Name = "FirstName", Order = 1, IsRequired = true)]
public String FirstName;

[DataMember(Name = "LastName", Order = 2, IsRequired = true)]
public String LastName;

[DataMember(Name = "ID", Order = 0, IsRequired = true)]
public Int64 PersonId;

[DataMember(Name = "Birthday", Order = 3, IsRequired = true)]
public DateTime DateOfBirth;

[DataMember(Name = "LastAccessDate", Order = 4, IsRequired = false)]
public DateTime LastAccessed;

}
[ServiceContract]
public interface IPersonService
{
[OperationContract]
Person GetPerson();
}

public class PersonService : IPersonService
{
public Person GetPerson()
{
Person person = new Person();
person.PersonId = 0L;
person.FirstName = "John";
person.LastName = "Smith";
person.DateOfBirth = DateTime.Parse("1990-10-01");
person.LastAccessed = DateTime.Now;
return person;
}
}

public class Service
{
public static void Main(string[] args)
{
ServiceHost serviceHost = new ServiceHost(typeof(PersonService));
serviceHost.Open();

Console.WriteLine("Running PersonService, hit any key to end.");
Console.ReadLine();
serviceHost.Close();
}
}
}


And here is the corresponding App.config file:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="WinCommFoundation.PersonService" behaviorConfiguration="personServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/wcfTest"/>
</baseAddresses>
</host>
<endpoint address=""
binding="basicHttpBinding"
contract="WinCommFoundation.IPersonService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>

<behaviors>
<serviceBehaviors>
<behavior name="personServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>


This created the following XSD:


<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" targetNamespace="http://philiptenn.com/wcf" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://philiptenn.com/wcf">
<xs:complexType name="PersonComplexType">
<xs:sequence>
<xs:element name="ID" type="xs:long" />
<xs:element name="FirstName" nillable="true" type="xs:string" />
<xs:element name="LastName" nillable="true" type="xs:string" />
<xs:element name="Birthday" type="xs:dateTime" />
<xs:element minOccurs="0" name="LastAccessDate" type="xs:dateTime" />
</xs:sequence>
</xs:complexType>
<xs:element name="PersonComplexType" nillable="true" type="tns:PersonComplexType" />
</xs:schema>

Wednesday, November 25, 2009

WCF Client

Visual Studio .NET 2008 provides a GUI interface for "Add Service Reference", which calls to svcutil.exe under the covers.


I created a new Windows Console project in VS.NET 2008 and right clicked on the project and selected "Add Service Reference", and was presented with the following dialog:





This generated the Client Proxy necessary to consume the Service. It actually created a new folder under my project called "Service References", and beneath that, an additional folder for each Service Reference.


Here is the client code that uses the generated proxy.


using System;
using WCFClient.ServiceReference;

namespace WCFClient
{
public class Client
{
public static void Main(string[] args)
{
GreetingServiceClient serviceClient = new GreetingServiceClient();
Console.Write(serviceClient.GetGreeting("Philip", "Tenn"));
serviceClient.Close();
Console.ReadKey();
}
}
}


My thoughts on this:

  • Really like being able to choose the namespace of the generated client proxy.

  • Creating the client code itself was simple ... just construct an instance of the GreetingServiceClient, and call the methods as if they were any regular class method. The details are hidden under the covers of WCF.

WCF Services

Next up: Exam 70-503: Windows Communication Foundation

Windows Communication Foundation Notes:



WCF was released as part of .NET 3.0, initially code-named Indigo. It is intended to support distributed applications and evolve from past attempts such as Remoting, Web Services, DCOM, and MSMQ.


It is focused on hosting, consuming, securing services to support distributed application.


It was enhanced as part of .NET 3.5 to support integration with Windows Workflow Foundation, as well as Web-based application support.

The "ABCs" of WCF are:

  • Address

  • Binding

  • Contract



Communication between WCF Clients and Service are done via channels. Messages are passed through the channel. The channel itself is composed of binding elements, which are stacks. The service endpoint provides a contract / interface. The WCF binding will define the channel, and there are built in bindings, such as BasicHttpBinding, WSHttpBinding, NetTcpBinding, and others.



Here is the list and definition of WCF System-Provided Bindings.

I wrote the following as my first WCF Service, based on examples in the book and on the Web.


using System;
using System.ServiceModel;
using System.Text;

namespace WCF
{
[ServiceContract]
public interface IGreetingService
{
[OperationContract]
String GetGreeting(String firstName, String lastName);
}

public class GreetingService : IGreetingService
{
public string GetGreeting(String firstName, String lastName)
{
StringBuilder greeting = new StringBuilder();
greeting.Append("Hello ");
greeting.Append(" ");
greeting.Append(firstName);
greeting.Append(" ");
greeting.Append(lastName);
return greeting.ToString();
}
}

public class Service
{
public static void Main(string[] args)
{
ServiceHost serviceHost = new ServiceHost(typeof(GreetingService), new Uri("http://localhost:8000/wcfTest"));
serviceHost.AddServiceEndpoint(typeof (IGreetingService), new BasicHttpBinding(), "");
serviceHost.Open();

Console.WriteLine("Running GreetingService, hit any key to end.");
Console.ReadLine();
serviceHost.Close();
}
}
}



The code sample above uses programmatic definition of the Service Address URI as well as the Bindings.

However, we could also declaratively define these in a web.config or app.config Configuration file.

Here is an example of an app.config file that provides the address, bindings, and exposes the Metadata Exchange information.



<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="WCF.GreetingService" behaviorConfiguration="greetingServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/wcfTest"/>
</baseAddresses>
</host>
<endpoint address=""
binding="basicHttpBinding"
contract="WCF.IGreetingService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>

<behaviors>
<serviceBehaviors>
<behavior name="greetingServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>



When I open the URL: http://localhost:8000/wcfTest, I see the following in my browser:


Passed Microsoft Exam: 70-505

Yesterday, I passed Exam 70-505: .NET Framework 3.5 Windows Forms Application Development.

In the evening, I went out and bought a book on Windows Communication Foundation. The book I got is "Essential Windows Communication Foundation For .NET Framework 3.5", by Steve Resnick, Richard Crane, and Chris Bowen. It's part of Addison Wesley's .NET Development Series.

I sat down at Borders and browsed through all the WCF books they had, and this one seemed to have the most information presented in a digestable manner.

I'm starting studies on WCF immediately.

Monday, November 23, 2009

SQL Server 2008 Express Edition

Since I'm going to be studying for an ADO.NET test soon, I figured I would need an instance of SQL Server on my home computer.

I went to Microsoft.com to download the free SQL Server 2008 Express Edition. I've used SQL Server 2005 in the past, but really haven't worked with 2008 yet.

I was presented with the following options:





I went to install "Runtime with Management Tools", since I have no need for reporting. I definitely need the runtime, and the SQL Server Management Studio that I worked with in SQL Server 2005 was pretty cool.

When I began the install process (they have a Web Installer now), I started getting an error message:





Turned out the problem was the the instance of SQL Server 2005 that was installed (probably as one of the options that I chose, though I can't recall) as part of my Visual Studio .NET 2008 Installation.

I went into Control Panel and uninstalled SQL Server 2005 Express Edition, and all of its dependencies (pretty much every program that started with the name "SQL Server"). I figured I'd uninstall the dependencies first, and finally SQL Server 2005 Express Edition last.

Turned out this was a big mistake. It basically ended up orphaning my SQL Server 2005 Express Edition, so that I couldn't fully uninstall it. So I ended up downloading and reinstalling SQL Server 2005 Express Edition SP3, and then uninstalling it.

This worked, and when I went back to install SQL Server 2008 Express, I got a new error message:





Getting closer! Just need to install VS.NET 2008 SP1.

Sunday, November 22, 2009

Deployment: ClickOnce

When reading about the Skills Measured for the Exam 70-505: Microsoft .NET Framework 3.5, Windows Forms Application Development, it appeared that a relatively high percentage of the exam (15%) was dedicated to ClickOnce.

I had done a lot of reading in the past about deployment strategies for Microsoft .NET Windows Application Deployment (ClickOnce, Installer, XCOPY), but really don't have much hands-on application, so I figured I'd begin my studies here.

Found the following starting point on MSDN about Deploying .NET Framework Applications.

Notes about ClickOnce:
  • Only supported by VB.NET and C# applications, not C++.
  • Publish Windows Forms, Windows Presentation Framework (WPF, formerly Avalon when I first started working with it), and Console Applications to a Publish Location (Web Server, Network drive, FTP Server)
  • ClickOnce Applications subject to CAS, Security Zone will depend on the Publish Location.

Passed Microsoft Exam: 70-564

I passed Microsoft Exam 70-564: Pro: Designing and Developing ASP.NET Applications Using the Microsoft .NET Framework 3.5 on Tuesday, November 17.

There really wasn't any new studying required from Exam 70-562: Microsoft .NET Framework 3.5, ASP.NET Application Development.

Things got incredibly busy at work this week (actually thought about rescheduling my exam, but I asked my manager and he said I should proceed with my exam).

So I passed it, got my Microsoft Certified Professional Developer (MCPD) distinction, and spent the rest of the week putting in tons of hours at work on optimizing SQL and performance tuning. Didn't touch my Microsoft Press books for the rest of the week.

I'm hoping to get back into it, starting with Windows Forms, when things calm down a bit at work.

Saturday, November 14, 2009

Passed Microsoft Exam: 70-562

I passed Microsoft Exam 70-562: Microsoft .NET Framework 3.5, ASP.NET Application Development on Friday (11/13/09).

Probably can't go into much detail due to the terms of the exam, all I can say is that it was painful and I walked out of the exam with a horrible migraine. Instead of writing sample code, I just crammed using the Microsoft Press book, Skills Measured, MSDN and various blogs.

Planning on going straight onto 70-564: Pro: Designing and Developing ASP.NET Applications Using the Microsoft .NET Framework 3.5

To be honest, I'm not planning to study for this test much (if at all). I have a feeling that having recently prepared thoroughly for and taken both the .NET Fundamentals and the ASP.NET App Dev exams, there should not be any new material.

Even if there is, hopefully, it should be a small enough percentage of the overall test that my preparation for the first 2 exams should be enough to pass.

ASP.NET Data Controls

I found an excellent article that highlighted the similarities and differences among ASP.NET Data Controls:

Understanding the Differences Among the DataGrid, DataList, and Repeater

I've used the DataGrid and Repeater in the past (never really used the DataList), but more often than not, I'd lose track of the subtle differences between ASP.NET data controls.

The biggest problem in my view is that the name really does not provide a clear picture of either the usage or the rendered HTML of the particular Data Control.

There's also the ListView (and its DataPager) that was introduced in 3.5. I've not had a chance to write actual code using ListView ... hoping to write at least some sample code, but I've been so busy cramming for the ASP.NET exams that I haven't been doing much hands-on .NET Development.

It's ironic, but I've found that most certification exams require a high-level understanding of a vast array of topics, and even when they occasionally delve in-depth, one is better served by reading quickly through a large book (like my Microsoft Press book) than writing an application that utilizes certain technologies (such as writing a Photo Gallery that uses ListView, Membership Providers, etc.)

Saturday, November 7, 2009

ASP.NET Page Lifecycle events

From my ASP.NET experience, understanding the Page Lifecycle and what occurs at each point is one of the most confusing (and important) aspects of ASP.NET development.

Here are the 2 MSDN pages that I've gone over several times and memorized:

There is also several pages in my Microsoft Press book that are very similar to these MSDN pages.

The challenge is remembering each of the events, and what is appropriate to do at that particular event. For example:

  • PreInit - Set Master Page, Set Theme, create dynamic controls
  • Init - Controls have been initialized, theme skins applied. Initialize control properties.
  • InitComplete - Perform tasks that require initialization has been completed.
  • PreLoad - Perform any processing that should occur before Load.
  • Load - Set properties in controls and establish database connections
  • Control Events (calling of delegates based on events raised, should check Page.IsValid if there are any Validator controls).
  • LoadComplete - Perform tasks that require load has been completed.
  • PreRender - Prior to this event occurring, Page calls EnsureChildControls for all controls, including itself. Also, all data bound controls have DataBind method called.
  • SaveStateComplete - ViewState has been encoded and saved, then this event occurs.
  • Render - Page object calls Render on every control.
  • Unload - event occurs for each Control, finally for the Page. Do cleanup, close database connections.
*sigh* I like ASP.NET, but I've tended to only use a few of these Lifecycle events (PreInit and Load) to keep things simple. They are SO granular, as you can see from the list above, and it's difficult to remember what-goes-where.

Wednesday, November 4, 2009

Microsoft Certification Studies: 70-562

Next up ... Exam 70-562: Microsoft .NET Framework 3.5, ASP.NET Application Development

The starting point for ASP.NET is the System.Web.UI namespace.

I've spent a lot of time on the MSDN site for this namespace, having done a lot of ASP.NET development work. I've practically lived on the API for Page and Control, and sites that document the ASP.NET Page Lifecycle, so this is more review and refamiliarization than anything.

However, I am sure there will be some new material I haven't been exposed to yet.

I'm also using the Microsoft Press book "Microsoft .NET Framework 3.5 - ASP.NET Application Development" by Mike Snell, Glenn Johnson, Tony Northrup, and GrandMasters.

Read through the first 2 chapters this evening.

Passed Microsoft Exam: 70-536

I passed my Microsoft .NET 70-536 exam today. Woo-hoo!

My primary approach to preparing for this exam was the Microsoft Press book that covered the exam, as well as just pouring over the MSDN FCL documentation.

I also wrote a lot of little test programs (some of which I ended up posting on my blog). I've done a lot of .NET development, but the Skills Measured (from Microsoft's site) covered a lot of aspects of the .NET Framework that I've never used (nor had a reason to use).

The biggest ones being:

- COM / Interop. I've done standalone .NET Windows Forms clients, installer programs, and a Globalized ASP.NET Website. Never had a reason / need to interface with COM. I just studied the book on this, read articles on sites like CodeProject.

- System.Diagnostics. Coming from the Java world, I had always used log4j for my logging needs, so log4net seemed like a good, practical solution. Consequently, I never needed to use Systems.Diagnostics.

This evening, after work, I immediately began studying for 70-562: ASP.NET Application Development.

It feels like being in college again, taking final exams. :-) Good times!

Tuesday, November 3, 2009

Systems Diagnostics

For some reason, this is one of those topics I've really dreaded about the exam. I guess it's because most of my .NET Development has been done on ASP.NET, using log4net for my logging.

Consequently, I've tended to stay away from the Systems.Diagnostic (the stuff that writes to the Windows Event Log).

Ah, well, this is a good time to learn it, since the exam covers it.

Here is a test program I wrote to use the System.Diagnostic.EventLog, as well as System.Diagnostic.Debug.


using System;
using System.Diagnostics;

namespace Diagnostics
{
class Program
{
static void Main(string[] args)
{
String applicationEventSource = "Test Diagnostic Application";
if (!EventLog.SourceExists(applicationEventSource))
{
EventLog.CreateEventSource(applicationEventSource, "Application");
}

// Use static method to write an entry. Default EventLogEntryType is Information
EventLog.WriteEntry(applicationEventSource, "Hello, world!");

// Try using instance-specific methods to write a test error
EventLog eventLog = new EventLog("Application");
eventLog.Source = applicationEventSource;
eventLog.WriteEntry("Test error", EventLogEntryType.Error);

// Test debug
Debug.Listeners.Add(new ConsoleTraceListener());
String testString = "Company";
Debug.WriteLine("Test");
Debug.WriteLineIf(testString != "My Company", "Incorrect Company");
Console.ReadKey();
}
}
}

Sunday, November 1, 2009

Cryptography

I've been playing with the System.Security.Cryptography namespace, making sure I'm familiar with the classes here.

I'm really starting to feel good about taking the .NET certification exam 70-536, think I'll do it next week. I've been studying hours every night, and going over the Microsoft Press study book by Tony Northrup, as well as just reading the MSDN .NET FCL.

Wrote the following test program that shows how to create an MD5 hash.


using System;
using System.Security.Cryptography;
using System.Text;


namespace SecurityTest
{
class Program
{
static void Main(string[] args)
{
String unencryptedPassword = "password";
String encryptedPassword = EncryptPassword("MD5", unencryptedPassword);
Console.WriteLine("Encrypted password is: '" + encryptedPassword + "'");
Console.ReadKey();
}

public static String EncryptPassword(String cryptAlgorithm, String unencryptedPassword)
{
HashAlgorithm hashAlgorithm = HashAlgorithm.Create(cryptAlgorithm);

byte[] hash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(unencryptedPassword));

StringBuilder s = new StringBuilder();
foreach (byte b in hash)
{
s.Append(b.ToString("x2").ToLower());
}
string password = s.ToString();

return password;
}
}
}