Friday, June 1, 2012

RESTful Services: Authenticating Clients Using Basic Authentication

Security is important... period. There is no getting around it and we should all have it in mind when developing services of any type. So today I want to speak to the 1st of 2 different mainstream methods used for authenticating client calls to your WCF RESTful service. This post will expand on my last post here titled: Creating a WCF RESTful Service And Secure It Using HTTPS Over SSL. Keeping in the same genre of services types as before, I am speaking about WCF RESTful Services hosted on the internet and authentication methods prominent to this type of scenario. For intranet based RESTful services, you can employ the help of Windows based authentication to authenticate clients inside a Windows domain. However with the popularity of exposing data in a RESTful manner via the internet and the lack of built in security (as opposed to the cradle that Windows can be), I am keeping this focus to the services exposing data for internet scenarios.

In my last post I showed that once you secured the service using a SSL certificate, you could now view a security context when debugging. This is important because now we need to populate that context so we can determine if we want to allow the client to be authenticated to the service, and then check to see if they are authorized for whichever method or operation they have requested.

Once again we can fall back to our knowledge of the web in general for this configuration. Basic Authentication is nothing new to RESTful or even WCF services in general. It is a 401 HTTP challenge/response mechanism to prompt the client for credentials. As we also know, 'Basic' authentication can get a black-eye because it is just a base64 encoded non-encrypted string that is not natively secure, unless used in conjunction with a SSL certificate to secure the transport of this sensitive information.

From my last post we configured a simple REST service using a security mode of 'Transport' with a SSL certificate, and we now need to configure the clientCredentialType attribute. If we add a <transport> element within our existing <security> parent element, we can select Basic as our clientCredentialType. Notice there are several options for this attribute and you can read about all of them here: HttpClientCredentialType Enumeration. You might be wondering about 'Digest' as the security mode, but it is not actually that much more secure than 'Basic' and requires the hosting server to be joined to a domain. As for the others like Windows and NTLM they are good in intranet or extranet hosted scenarios. The 'None' option is the default option, but the whole point of this conversation is about securing our service, so we don't want to use that. The 'Certificate' option will be the focus of my next post on another mainstream way to secure our internet facing RESTful service. Our focus continues to be on using Basic authentication as displayed below:

<bindings>
  <webHttpBinding>
    <binding name="webHttpTransportSecurity">
      <security mode="Transport">
        <transport clientCredentialType="Basic"></transport>          
      </security>
    </binding>
  </webHttpBinding>
</bindings>

Our next step is to configure the service to point to a custom user name and password validator method that we will create shortly. Within our <serviceBehaviors> element we can configure the <servicecredentials> element and dictate that we want to use a Custom 'userNamePasswordValidationMode' value. We need to do this so we can intercept the credentials provided by the client via the request message header.

<serviceBehaviors>
  <behavior name="SecureRESTSvcTestBehavior">
    <!-- To avoid disclosing metadata information, set the value below to 
         false and remove the metadata endpoint above before deployment -->
    <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
    <!-- To receive exception details in faults for debugging purposes, set the value below to true.  
         Set to false before deployment to avoid disclosing exception information -->
    <serviceDebug includeExceptionDetailInFaults="false"/>

    <serviceCredentials>
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="RESTfulSecuritySH.CustomUserNameValidator, RESTfulSecuritySH" />
    </serviceCredentials>

   </behavior>
</serviceBehaviors>

Notice above that I have already provided a name for the class which will intercept and validate these credentials: 'CustomUserNameValidator'. The overridden 'Validate' method in this class will allow us to check if the user accessing our service is going to be authenticated. In the call stack, this method we are going to create will be called prior to the method being requested, so if authentication fails it will happen prior to accessing anything else inside the service. This code snippet that will follow is a close derivative to one that came from the MSDN (here: http://msdn.microsoft.com/en-us/library/aa702565.aspx).

public class CustomUserNameValidator : UserNamePasswordValidator
{
  // This method validates users. It allows in two users, user1 and user2
  // This code is for illustration purposes only and 
  // must not be used in a production environment because it is not secure. 
  public override void Validate(string userName, string password)
  {

    if (null == userName || null == password)
    {
      throw new ArgumentNullException("You must provide both the username and password to access this service");
    }

    if (!(userName == "user1" && password == "test") && !(userName == "user2" && password == "test"))
    {
      // This throws an informative fault to the client.
      throw new FaultException("Unknown Username or Incorrect Password");
      // When you do not want to throw an informative fault to the client,
      // throw the following exception.
      // throw new SecurityTokenException("Unknown Username or Incorrect Password");
     }
  }
}

Looking at the code above we see that we are able to inspect the username and password values to authenticate a user to the service. At this point you are seeing that this is preforming service level authentication and is more coarse grained than some of the method level authorization we will see in a minute. The point of this code is to validate if the client making the call has access to your service.

It should go without saying that you would not use the simplistic implementation from the code above. More than likely, you would probably make a call to a database to validate if the user's credentials are valid as opposed to hardcoding the logic. If the credentials are validated, control will pass on to the originally requested method. The 'Validate' method is void so there is nothing to set or return once authorized. It's a 'no news is good news' type of functionality, where exceptions should be raised only when there is an authentication issue.

This custom method of authenticating users is different as opposed to those of you that have overridden the 'CheckAccessCore' when using a defined 'serviceAuthorizationManagerType' that returns a bool indicating if the user is authorized. Since we are validating the username and password, configuring a value for the 'customUserNamePasswordValidatorType' is exactly what we need.

At this point test out what we have done, by starting your service (e.g. WCF Test Client) and make a call to the 'Customer' method as we built in my last post. This time we will be prompted for credentials by the browser.


Upon entering the correct credentials (username = "user1", password = "test") we get the returned JSON results expected. All of this authentication happened securely because our RESTful service is secured with a SSL certificate. Also note these credentials can be assigned programmatically in whatever language you are using. The beauty of REST services is they are platform and language agnostic and rely on the standards of the web and HTTP. If you happen to be a .NET client calling the service, then you would add the credentials to the request header as shown below:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"https://DevMachine1234:8099/MyRESTServices/Customer/1");
//Add a header to the request that contains our credentials
//DO NOT HARDCODE IN PRODUCTION!! Pull credentials real-time from database or other store.
string svcCredentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("user1"+ ":" + "test"));
req.Headers.Add("Authorization", "Basic " + svcCredentials);
//Just some example code to parse the JSON response using the JavaScriptSerializer
using (WebResponse svcResponse = (HttpWebResponse)req.GetResponse())
{
  using (StreamReader sr = new StreamReader(svcResponse.GetResponseStream()))
  {
    JavaScriptSerializer js = new JavaScriptSerializer();
    string jsonTxt = sr.ReadToEnd();
  }
} 

Now try entering incorrect credentials (in code or in a browser) and make the same REST call. This time as expected and exception is thrown, the client receives a HTTP 403 Forbidden, and we are not permitted to view the results or access the service.


The next and final step here is to take the provided client context a step further with authorization at the method level. The reason for doing this is to offer fine grained security at the method level. For example if you are hosting a RESTful weather service with 10 methods, but only 7 of the methods are served up to everyone and the remaining 3 are for paid subscribers only. In this case we need to preform authorization at the method level.

Remember from my last post I mentioned the importance of the 'ServiceSecurityContext' object. Here is where it will come into play. This is populated with the client's context after being validated by our custom 'Validate' method. Within the ServiceSecurityContext instance the 'PrimaryIdentity' is populated with an instance of System.Principal.Identity.GenericIdentity that contains the properties we need to determine if this user is authorized to the requested method.


The code below will examine this instance and determine if the call can proceed:

//NOTE: This code is within the actual method call (e.g. GetCustomer CLR method)


//Get current SecurityContext to inspect below for authorizing
ServiceSecurityContext securityCtx;
securityCtx = OperationContext.Current.ServiceSecurityContext;

//This code is a bit primitive and ideally you would call off to another method here that would 
//perform the logic and probably just return a bool value as in commented out line below:
//if (CheckIfAuthorized(securityCtx) != true)
if ((securityCtx.PrimaryIdentity.IsAuthenticated != true) || (securityCtx.PrimaryIdentity.Name != "user1"))
{
   throw new UnauthorizedAccessException("You are  permitted to call this method. Access Denied.");
}

If you use the "user1" account you can see that we are indeed both authenticated to the service and authorized to call this method. However, now try and log back into the service with the "user2" account. This account is authenticated to make calls to the site, but not authorized to call this method. Once again you would not hardcode this logic, but rather be calling out to a security file or database to determine the authorization for this user and returning a bool more than likely. This provides that method level fine grained security that many services require.


So to wrap this up, you can implement a well know HTTP authentication method in 'Basic' authentication to secure your RESTful services. We can then take the context of the authenticated client call a step further and implement fine grained authorization at a method level to limit access to methods when needed. By using a well know security protocol that has been secured with SSL over HTTPS, you will broaden your services use and popularity using well know security practices.

Thursday, May 24, 2012

Creating a WCF RESTful Service And Secure It Using HTTPS Over SSL

Well I have had a few posts now on security, and focused some specifically on HTTPS and WCF. One of the most popular types of services we can create using WCF are RESTful services. The REST architecture and RESTful services have become so popular due to their inherent flexibility and being more consumer and platform agnostic as opposed to their WCF SOAP WS-* counterparts. However with this popularity and quickly expanding use we must not forget about securing our RESTful services especially when exposing them for wide use on the internet. Since REST services communicate over HTTP, we can leverage our existing knowledge and security principals we use for traditional websites that communicate over HTTP.

I wanted to highlight a few options for securing and authenticating to RESTful services using WCF in some upcoming posts. This 1st one will speak to securing the pipeline that REST services communicate over which is HTTP.

As we all know (or if not, now you do!) you can secure the communication over HTTP by using a SSL certificate. This is the 1st step in securing the data being communicated from the client and our RESTful service. Let's begin by looking at our simple ServiceContract. It contains a GET method defined with a CLR name of 'GetCustomerData' being exposed as the noun 'Customer' to adhere to REST architecture standards:

namespace RESTfulSecuritySH
{
   [ServiceContract]
   public interface ISecureRESTSvcTest
   {

     [OperationContract]
     [WebInvoke(Method = "GET",
                ResponseFormat = WebMessageFormat.Json,
                UriTemplate = "/Customer/{CustID}")]
     Customer GetCustomerData(string CustID);
   }
}

Behind the scenes the implemented code is returning the ID provided along a 'Customer' data contract with a some fake customer data. Obviously in a real implementation we would be connecting to a data repository to get this information, but for this example we will just hardcode values to be returned as security is the focus here and not the service implementation details.

namespace RESTfulSecuritySH
{
  public class SecureRESTSvcTest : ISecureRESTSvcTest
  {
     public Customer GetCustomerData(string CustID)
     {

        Customer customer = new Customer()
        {
          ID = CustID,
          FirstName = "John",
          LastName = "Smithers",
          PhoneNumber = "800-555-5555",
          DOB = "01/01/70",
          Email = "jsmithers@fancydomain.com",
          AccountNumber = "1234567890"
        };

        return customer;
     }
  }

  [DataContract]
  public class Customer
  {
     [DataMember]
     public string FirstName { get; set; }
     [DataMember]
     public string LastName { get; set; }
     [DataMember]
     public string PhoneNumber { get; set; }
     [DataMember]
     public string DOB { get; set; }
     [DataMember]
     public string Email { get; set; }
     [DataMember]
     public string ID { get; set; }
     [DataMember]
     public string AccountNumber { get; set; }
  }
}

The default configuration for this service uses the webHttpBinding as required for RESTful services created using WCF. This configuration is for a self-hosted service as it provides a *baseAddress* value. This identical configuration could be used for an IIS hosted service. Just keep in mind the *baseAddress* will be ignored and replaced by the virtual directory structure set up in IIS.

<system.serviceModel>
  <services>
    <service behaviorConfiguration="SecureRESTSvcTestBehavior" name="RESTfulSecuritySH.SecureRESTSvcTest">
        
      <host>
        <baseAddresses>
          <add baseAddress="http://DevMachine1234:8099/MyRESTServices/"/>
        </baseAddresses>
      </host>

      <!--webHttpBinding allows exposing service methods in a RESTful manner-->
      <endpoint address=""
        binding="webHttpBinding"
        behaviorConfiguration="webHttpBehavior"
        contract="RESTfulSecuritySH.ISecureRESTSvcTest" />

      <endpoint address="mex"
        binding="mexHttpBinding"
        contract="IMetadataExchange" />

    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="SecureRESTSvcTestBehavior">
        <serviceMetadata httpGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="false"/>
      </behavior>
    </serviceBehaviors>

    <!--Required default endpoint behavior when using webHttpBinding-->
    <endpointBehaviors>
      <behavior name="webHttpBehavior">
        <webHttp/>
      </behavior>
    </endpointBehaviors>

  </behaviors>

</system.serviceModel>

At this point if we start our service using the WCF Test Client (if trying this locally), and then call the RESTful URI http://DevMachine1234:8099/MyRESTServices/Customer/8 to our service, you will get the JSON output (below) as expected (use Chrome, FF, or Safari to test. IE and Opera make you open a separate file). 'DevMachine1234' is the name of my dev box and eventually will be the name that needs to match up with the one provided to the SSL certificate which we will discuss in a moment.

{"AccountNumber":"1234567890","DOB":"01\/01\/70","Email":"jsmithers@fancydomain.com","FirstName":"John","ID":"8","LastName":"Smithers","PhoneNumber":"800-555-5555"}

OK, simple enough but notice there is data here that really is sensitive. The structure and design of our Customer data contract is not the focus of this post and is a flattened view of example customer data, but regardless some of it is sensitive. Let's now secure the transmission of this data over HTTPS using a SSL certificate.

For this example I am going to use a self-signed certificate I created locally and assign it on my machine to port 8099. I have (2) posts already that explain how to do this: Create A Self-Signed SSL Certificate Using IIS 7 and Applying and Using a SSL Certificate With A Self-Hosted WCF Service.

Let's focus on the configuration changes that had to be made. Now depending on how you decide to host your WCF service there may be subtle differences in the configuration. Also I should mention here that all of the configuration can be done in code if you chose to do so. I typically prefer configuration 1st, and only rely on using code to configure and run my service if there are elements that could be different at runtime and the configuration needs the flexibility of being dynamic. If this is not the case, I lean toward configuration because of its on-the-fly configurability and ease of reading. This is one case where either method works fine.

If using IIS to host your service, the certificate can be added through the IIS Management console and applied to the site instead of using the command line netsh.exe tool for self-hosted services. The 1st configuration change is to update the base address if you are using a self-hosted service to HTTPS:

<add baseAddress="https://DevMachine1234:8099/MyRESTServices/"/>

Next we must add a bindingConfiguration value to our endpoint as shown below:

<endpoint address=""
     binding="webHttpBinding"
     bindingConfiguration="webHttpTransportSecurity"
     behaviorConfiguration="webHttpBehavior"
     contract="RESTfulSecuritySH.ISecureRESTSvcTest" />

We must also add in this new binding configuration section. If you add a bindings section at the root of the system.serviceModel section, we can configure the security to be "Transport". When using Transport security with WCF, it automatically expects we want to use HTTPS for our endpoint. There are (3) different modes in the enumeration for the security element: None, Transport, and TransportCredentialOnly. 'None' indicates there is no required security on the endpoint, 'Transport' indicates we want to secure our endpoint with a SSL certificate using HTTPS, and 'TransportCredentialOnly' provides HTTP-based client authentication only and does not provide message integrity and confidentiality. The new endpointConfiguration is below:

<bindings>
  <webHttpBinding>
    <binding name="webHttpTransportSecurity">
      <security mode="Transport" />
    </binding>
  </webHttpBinding>
</bindings>

Next within the service behavior we must enable HTTPS and disable HTTP. This way our RESTful service can only be accessed via HTTPS. This is a very important step if you intend to have your service only accessed in a secure manner. Otherwise you leave the door open to still access it via HTTP. This may be an OK scenario if hosting non-secure data that you want to be able to be accessed via HTTP or HTTPS, but otherwise it should only be one or the other.

<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>

Lastly, we need to update the metadata publishing endpoint to use HTTPS as well:

<endpoint address="mex"
  binding="mexHttpsBinding"
  contract="IMetadataExchange" />

At this point restart your service. If you encounter any errors, it is probably because the SSL certificate does not match the name of your service, the SSL cert has not been applied correctly to the port (self-hosted services only), or the all the configuration updates were not made correctly. If you completed everything successfully, you can now access your site at the following URL: https://DevMachine1234:8099/MyRESTServices/Customer/8

Now try opening a new browser and access it via HTTP; it will not work and this is what we wanted. We have now secured our RESTful service's communication.

One last big ticket item here that will set me up for my next posts on securing RESTful services has to do with the security context before and after securing our service. This will ultimately allow us to authenticate our users and move forward with security. Either debugging the RESTful call to your existing 'GetCustomer' method or from a new call that simply returns a string, try looking at the following lines of code:

//Look at the ServiceSecurityContext both using secured and non-secured service configurations:
ServiceSecurityContext svcSecurityContext;
svcSecurityContext = OperationContext.Current.ServiceSecurityContext;


Notice how if you run your service without Transport security using HTTPS, the ServiceSecurityContext instance will be 'null'. However once we secure our service, this instance will have value. Specifically if you look at the .IsAnonymous property, you will notice it is now = "true" upon securing our service.


We will work on populating this value in my next post and moving forward to authenticating the client.

Thursday, May 17, 2012

Fixing The SignatureMismatchException When Updating NuGet

Recently I was trying to update the NuGet Package Manager for VS.NET 2010 from version 1.6.x to 1.7.x and ran across the following exception in the log presented when there is an error with the update process:

VSIXInstaller.SignatureMismatchException: The installed version of 'NuGet Package Manager' is signed, but the update version has an invalid signature. Therefore, Extension Manager cannot install the update. at VSIXInstaller.Common.VerifyMatchingExtensionSignatures(IInstalledExtension installedExtension, IInstallableExtension updateExtension) at VSIXInstaller.InstallProgressPage.BeginInstallVSIX(SupportedVSSKU targetAppID)
Install Error : VSIXInstaller.SignatureMismatchException: The installed version of 'NuGet Package Manager' is signed, but the update version has an invalid signature. Therefore, Extension Manager cannot install the update at. VSIXInstaller.Common.VerifyMatchingExtensionSignatures(IInstalledExtension installedExtension, IInstallableExtension updateExtension) at VSIXInstaller.InstallProgressPage.BeginInstallVSIX(SupportedVSSKU targetAppID)


The fix is simple; it requires an uninstall and reinstall. I assume updates within a version would work, but since I am actually upgrading I imagine this is what requires the uninstall 1st.

Go back to the Extension Manager and select "Installed Extensions", and then select the NuGet pacakage and press "Uninstall". Close and reopen the Extension Manager to refresh the installed packages, and search the Online Gallery for NuGet. If ordering by "Highest Ranked" it typically is the 1st or close to 1st item in the list. Now select "Download" and the installation will complete successfully.

Thursday, May 10, 2012

Adding The HTML Target Schema Selection to VS.NET 2010 for HTML5 Intellisense


If you are beginning to delve into HTML5 in VS.NET say in a MVC3 project using the Razor engine for example, you will want intellisense support for HTML5. This is not difficult to do, but the 'HTML Source Editing' toolbar may not be shown by default in your VS.NET instance. To add it preform the following steps:

1. Open VS.NET but do not open any specific project. This ensures the changes you make will be for all project's opened.

2. Go to 'View -> Toolbars' and select the 'HTML Source Editing' menu item.


3. To test, open a MVC3 or MVC4 project using the Razor engine and navigate to a .cshtml view. The dropdown will now be active and the default selection will be 'XHTML 1.0 Transitional'. Change it to 'HTML5'.


4. Now try typing in the first few letters of a HTML element or attribute, like the 'Canvas' tag.


You now have the HTML5 schema validation and intellisense support.

Monday, April 30, 2012

Using WCF Data Services Tutorial - Part 1

With the recent release of WCF Data Services 5.0 a few weeks ago, I thought it would be a good idea to introduce the technology to those of you that have not seen it before. 

WCF Data Services for those of you used to creating traditional SOAP based or REST services using WCF has a different purpose and use. It builds upon the Open Data Protocol (OData) that Microsoft created to expose data as resources that are addressable by URIs. OData builds upon the AtomPub protocol to represent data in a standardized method and then makes it accessible via HTTP. Through REST based services you can access any type of data using the standard HTTP verbs (GET, POST, PUT, DELETE).

These services offer a powerful way to quickly expose your data as services without a lot of the manual work involved otherwise. In addition the services are customizable via service operations and interceptors. The OData protocol is something not confined to .NET either. The idea is an open protocol for exposing your data in a platform agnostic manner via HTTP. There are a slew of .NET OData client libraries that sit atop of data services for accessing the data, and there are even libraries in other languages like Java and its OData4J library.

So why is this good? Well 1st off we are exposing data using a known and standardized protocol in OData. Think of the alternative using a traditional WCF service with a webHttpBinding to create a RESTful service. You would be creating from scratch how your data is being exposed and only you and your clients understand this model; it is not a standard. If you being on new clients to consume your services, you have to explain (typically through documentation) on how your data looks when exposed. This is obviously not as easy as telling clients that your services expose data that is built upon the AtomPub format in OData which is a standard. The other main attraction of data services is how much custom and manual plumbing work that gets cut out and streamlines. As you will see below, in just minutes I can have my relational data exposed and accessible via HTTP in a RESTful manner via URIs mapped to my entities.

In my example I am going to expose some relational data via WCF Data Services from the 'AdventureWorks' database on my local SQL Server instance. I just want you to get up and running to see the possibilities, so we will go through all the steps to preform a simple GET on some of the entities we will expose.

First let's start off by creating an Entity Framework model for the  AdventureWorks database. If you want to follow along and do not have the Adventureworks database you can download it from CodePlex here: (http://msftdbprodsamples.codeplex.com/). Begin by going to 'Add -> New Item' and under the 'Data' category on the left select 'ADO.NET Entity Data Model'.


For this example I am using the AdventureWorks database, so I select 'Generate from database' and then navigate through the wizard to set up a connection, naming conventions (I use the default values for this example), and then I selected all the tables before completing the Entity Framework Model.


Now that our EF model is created, we can create our WCF Data Service. I have the new WCF Data Services 5.0 installed which is built upon the OData v3.0 specification, and you can download it from here as well: http://www.microsoft.com/en-us/download/details.aspx?id=29306 In Solution Explorer on your project, select 'Add -> New Item' and under the 'Web' category on the left select 'WCF Data Service (for OData v3)', or similar option if you have an older version of WCF Data Services installed.




This will create a new WCF Data Service with it's default class and 'InitializeService' method. On this class we must Implement the Entity Framework model we created earlier. The default line below instructs you to do so:
public class WcfDataService1 : DataService< /* TODO: put your data source class name here */ >
For this example let's Implement the 'AdventureWorksEntities' class we created earlier like below:
public class WcfDataService1 : DataService<AdventureWorksEntities>
The next step requires us to be explicit on which entities we want to expose and with what level of permissions too. Just to give you a feel of what the exposed data representation looks like in the browser, lets go ahead and expose all entities using the asterisk with 'AllRead' permission:
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
Before viewing the data in the browser, I recommend selecting the browser for VS.NET to use to Google Chrome instead of IE. IE9 at least does not display AtomPub data properly (See UPDATE at the end of this post for using IE), and upon doing a GET on the entities you not be able to view the data. To do this, right-click the WCF Data Service item in Solution Explorer and select: 'Browse With...' as shown below. Select 'Google Chrome' and the browser will display all of the entities that have been exposed. You can also permanently switch the default browser used in this dialog as well by pressing 'Set as Default'







As you see above, all of the 'Collections' from our EF model are exposed. Let's go ahead and only expose the 'Employees' entity by modifying the code to look as follows:
//Only allow the Employees entity collection to be exposed:
config.SetEntitySetAccessRule("Employees", EntitySetRights.AllRead);

//
Now when run in the browser we see only the Employees collection is exposed. Let's explore and expose what information we can get back on this collection by modifying the URI. If I want to get back the Employee with ID '1', I can simply request this using the URI below:



Upon making the GET request, you can see that I get back all of the information just for the Employee with the ID of '1'. 


One other nice feature is the ability to query the entity with some predetermined query string options. For example, when we did a GET for the Employee with an ID=1, you could see there were some related entities 'Employee1' and 'Employee2'. If we use the 'expand' query string option, we can expand on this employee to see related entity information. Modifying the URI to be as follows to expand on the 'Employee1' many to many relationship:



Upon making the GET request with the expand query option you will see the additional related entity information. Try the same procedure for expanding on 'Employee2' to see additional related entity information.

So look at this - in just a few minutes we are up and running by exposing our relational data accessible via HTTP in a RESTful manner using a know open protocol. Pretty cool if you ask me, and even better - really useful. This has just barely scraped the surface of what can be done with WCF Data Services. In the future I will expand on this tutorial getting a little more in depth with some of the additional functionality offered.

UPDATE: To get IE to format the OData as XML, do the following:
  • Tools -> Internet Options
  • Select the Content Tab
  • Under 'Feeds and Web Slices', select 'Settings'
  • Under the 'Advance' section deselect 'Turn on Feed reading view'

Wednesday, April 25, 2012

The Future of Creating Line of Business and Metro Applications in Windows 8


So with Windows 8 right around the corner and a software community racing hard to adopt and create new Metro style applications, I thought it would be a good time to focus on Line of Business applications in the future. My posts on Windows 8 evolve with my increased exposure to the new OS, and it is fun to see how my opinions evolve as well.

I get Windows 8 and I am sold. But guess what? I am a software engineer. Even if I did not like Windows 8 (which is not a problem because I do) I would end up adopting it anyways any new OS from Microsoft will make its presence known... eventually and in 1 way or another. 

However this is somewhat a radical change to current Microsoft OS interaction experiences from the last several OS releases dating back to Windows 95. In fact I made that observation myself in an older post, and many in the industry say as well that: "This is the biggest change to an OS from Microsoft since Windows 95." I even hear examples trying to pull parallels to how people didn't understand how to use a mouse back in Windows 3.1 and everyone had to be taught on its use. Thus trying to draw the line that we just need to educate people on the new changes and ways of thinking in Windows 8. I have a problem I have with that analogy - most people had little if no personal computer experience back in the early 90's and nothing to draw on or compare to so everything was new.

This isn't the case this go around. Roughly 80% of households have a computer in the U.S. and the majority of them are probably running Windows XP or Windows 7. People are getting comfortable and are used to "a way" of doing things on their Windows computer. A lot of that at least from an interaction standpoint will change with Windows 8. Most industry tech people and software engineers will have no problem adapting. It's the 65 year old user that is still asking: "Why are my folders sorted from Z-A all of the sudden??" that is going to have a problem with radical change. This too will spill over into the workplace and into LOB applications.

There is a familiarity with most LOB applications whether web or desktop that users feel comfortable with. Metro style applications will shake up that feeling of comfort if corporations begin to move to Windows 8. The natural slowness of larger corporations to change their OS will actually help ease this new (and improved) look and feel of Windows 8 into general society 1st through home computers, tablets, and mobile phones. This will allow users to become more familiar with Windows 8 and its Metro interface well before it is rolled out in large use in the corporate world in my opinion.

So will the new Metro style work for LOB applications? The answer: absolutely. Challenges? absolutely. Will Windows 8 and its new metro interface catch on to the masses? I believe it will and also hope it will. I think Microsoft has done a good job in what I have seen of Windows 8 and I’m definitely a proponent of it. However I am a realist as well and know (as they do too) the challenges we face.

Challenge 1: Bend our (software developers) minds to create Metro style LOB applications. OK, so how many developers out there have ever said: "I am not a UI guy/gal." Well if you are lucky enough to work on a ginormous team that has front end developers, then Windows 8 will offer not much for change in that aspect. However for most of us that are involved with end to end development you are going to have to bend your mind to learn the new 'Metro' style.

VS.NET 2011 has provided templates for guiding those of us deficient in UI design on creating Metro style apps and this will help. But even a template will not undo 10-20 years of the way we have done web and desktop development for LOB applications. You know the old 'File' menu at the top, close button on the top-right, status bar at the bottom. Gone or construed into something new and not totally 1:1 in translation when creating a metro app. Essentially the 'Chrome' of today's applications is gone and a dirty word in Windows 8. I have heard and quote (loosely) Rocky Lhotka at VSLive! say repeatedly when working with XAML and joking about himself not being a UI guy stating: "I know one color: Battleship Grey, so yeah I appreciate the designers." Well a lot of us are going to be in this boat (no pun intended). Metro style apps place a great emphasis on the UI interaction and design and being good at this will be important. No longer will slapping a lot of text boxes and labels on a form suffice, if we want to move forward and truly use Metro applications. This is a good segue into my next challenge below.

Challenge 2: Switching back to the classic desktop and applications in Windows 8. So the 1st adopters of Windows 8 in the business world will obviously not have enough time to redesign their application portfolio into Metro style applications. So what will happen? Upon clicking a ‘tile’ on the Metro Start screen for your LOB application, you will be reverted to the traditional Windows Desktop and existing application. This switching back between the Metro Start menu and the classic desktop is something that I believe will annoy and confuse the general use population. It's not a big deal and happens somewhat seamlessly, and is absolutely necessary for backwards capability of existing applications. Like Microsoft keeps stating: "If it runs on Windows 7, it will run on Windows 8." The problem is some of these behemoths of LOB enterprise applications may never be converted to a Metro style app (might still be half a million lines of code in VB6!) so this switching back and forth needs to be looked at by the community and feedback given as to make this as seamless as possible.

I honestly think eventually after enough pushback from users of the annoyance and how some may never want to adopt the Metro interface (not saying I agree, just being a realist), that Microsoft would serve up an option in its 1st service pack (SP1) for Windows 8 to switch permanently to 'Classic' mode or even have an install switch for 'Classic Only' mode. It would not surprise me 1 bit if they felt the squeeze and sales were low due to the new interface to make a move like this. However I think this would only happen as a move of desperation for sales. Microsoft will want to drive users to their new interface and get users to stop thinking of the 'old way' of doing things. I would not be surprised either way, and it will be interesting to see.

Challenge 3: Users becoming familiar with Metro style applications. No more application 'Chrome'. No more minimize, maximize, file menu, 'x' button to exit, etc. Start learning to 'swipe' your finger or mouse instead for menus that slide out from the top and bottom and left and right. I'm cool with that. Is everyone else? The obvious answer is no. I listen to a local AM radio computer show on my way to bowling on Tuesday night and you should hear the questions asked on the air: "What's this email about inheriting 90 million from Nigeria?" "How do I save a file from my granddaughter sent to me in an email?" "Where is MyDocuments in Windows 7?" Yeah... that's your general use population. Tell them: "Swipe your finger from the side to view more applications." The response? "Do I do this on my keyboard or in the air? My 14" dell monitor is not responding when I touch the glass on the screen..."

Of course then you have the folks that camp out in N.Y. 2 weeks before the next iPhone release so as a whole we are getting more tech savvy. These are the type of folks that will help move Windows 8 along, in addition to a strong following in the development community from people such as me. The tech group adopting Windows 8 will have no issue with its new look and feel and will probably enjoy it immensely.

On the LOB application front, users in the corporate world will have to adopt Metro applications using a mouse more than likely because any sort of touch device from a cubical that is sat in for 8 hours a day is not practical. Now for apps that need mobility (i.e. shipping, inventory, medical, etc. out on the floor or in a warehouse) Windows 8 is going to be positioned well. It's all these diverse groups with their experience and the minds to make large scale IT decisions in the business world that will determine how quickly Windows 8 and Metro applications catch on in that environment.

Challenge 4: Not getting stuck in the past and moving forward. This is a big hurdle. Why do we need this fancy new doodad of an interface (says the user that loves their stable Windows XP machine)? Well we don't technically need it but it really is aligning with where technology is and has moved. Look at everyone with smart phones today. If you enjoy any type of smart phone with touch capability, then Windows 8 will fall right in line and even expand on that use to all needs. In the business world where things tend to be a little more conservative (like using Windows 95 in 2002 for a company I worked for with 125,000+ employees), it will take more time. In addition this is not just "another OS".

Windows 8 and its Metro start menu and interface with redesigned and rethought applications are radically different. However at the end of the day they serve up the same functionality you get today; just in a prettier and cooler interface (along with superior OS engineering under the covers). I see a divide with Windows 8 in the corporate world and LOB applications and think it will be slow to catch on for larger existing applications. Once companies do make the switch, I think there will be a great hunger though from the software developers to create new development using Metro style applications. This will ultimately help move us all forward.

So what does all of this add up to? I think for the corporate world and most users of the Windows Operating system, full on Metro interaction with 100% Metro applications (or close to it) is many, many years down the road. In fact right now there is so much focus on getting developers to create a Metro application for the Windows Marketplace (to sell or download for free) to compete with Apple and Android market share that not as much focus is on complex LOB applications and development. The Marketplace isn't really applicable to internal corporate LOB HR or Accounting applications for example, so there isn't much talk on this front from what I can see. The push is to increase Windows market share and make Windows 8 a "one size fits all, touch first [tablet first if you ask me]" OS.

I think Metro style LOB applications will happen but will be much slower to be commonplace, and will follow behind the next 'HappyBunny' or 'AngryBirds' Metro app downloadable from the Marketplace. And to be honest there is nothing wrong with this. Microsoft needs to position itself well and be competitive in a niche right now that they know and I believe them to be behind. LOB applications are not going away and are safe, so the focus has shifted away a bit from any primary development discussions or new technology buzz. The real purpose of this post was just to provide some idea or insight as to how this new Metro style world will eventually make its way into the larger and broader corporate world and development in the years to come. Just be patient because it will take some time.

Wednesday, March 21, 2012

How To Handle OnChange / SelectedIndexChanged Type Event In JavaScript For The AJAX ComboBox

If you have ever used the AJAX ComboBox control and needed to interact with it client side in JavaScript, you will notice it's a bit of a different animal than it's ASP.NET server control counterpart: the DropDownList. If you want to get either the selected text or its value from a traditional DropDownList, all you needed to do was add an JavaScript function call to the 'onchange' client side property on the control like below:
<asp:DropDownList ID="AspNetDDL1" runat="server" AppendDataBoundItems="true" 
onchange="dropDownListOnChange(this);">
<asp:ListItem Text="( Select a Color )" Value="0" />
<asp:ListItem Text="Red" Value="1" />
<asp:ListItem Text="White" Value="2" />
<asp:ListItem Text="Blue" Value="3" />
</asp:DropDownList>
The JavaScript method for getting the value from an ASP.NET DropDownList is just as trivial as shown below. It will fire the alert each time a valid selection is made.
function dropDownListOnChange(sender) {
if (sender.value = 1) {
alert('You selected Red!');
}
else if (sender.value = 2) {
alert('You selected White!');
}
else if (sender.value = 3) {
alert('You selected Blue!');
}
}
However the AJAX ComboBox is a bit different and not just some user control inheriting from the ASP.NET DropDownList with all of the same properties and events. The AJAX ComboBox is built from the ground up, and when rendered to the client is comprised of (4) main parts:

- A text box showing the selected item.
- A button to press to show the list (usually a down arrow)
- An unordered list with all of the items bound.
- A hidden field with the selected value.

Now the common misconception is to try and handle client side events on the textbox or the unordered list like 'blur', 'keydown', 'keyup', 'change', or 'mousemove'. The problem is none of the events used individually or collectively (jQuery allows binding to multiple events easy) work perfectly. It requires the user to tab off the field, move the mouse, or some other action before the JS function gets called. That's not ideal at all as the selection from the ComboBox might be the only control on a page, or the last one on a page, and the client doesn't do any of the actions required. If for example the result of your wired up JS function is to show/hide other controls, then you want the JS function to fire immediately without delay and as it should.

The answer lies in some 'hard to find' documented events that can have functions assigned to handle these events. Specifically for this topic we are speaking of the add_propertyChanged event handler. We need to wire up this handler to our AJAX ComboBox client side which will then allow us to get the selected item or value client-side without having to make an expensive server trip. The documentation on the event handler is below:

Sys.Component.propertyChanged Event

As a side note, always keep this advice in mind. If you are a web developer and especially an ASP.NET webforms developer, it's all too easy to get lazy and inefficient by doing everything server-side. Why? Because you can! And how do we masquerade expensive server trips? With AJAX UpdatePanels, yeah! Don't get me wrong, I really like asynchronous postbacks with UpdatePanels and use them often, but make sure to use them when you actually need to go server side to make a call. If you make a dropdownlist, radio button, checkbox, or other server control go server side just to show another hidden row, add a control, or change some visual state, then you are bloating the time it takes to run your code and making a bad choice but not handling things that can take place 100% client side on the client. With all the JS explosion recently with libraries like jQuery there is no reason not to handle these types of needs client side.

Back on the AJAX ComboBox, we need to assign a function to the add_propertyChanged event handler on our control. Remember to get the ClientID of the value for server controls, as you cannot just pass in the raw ID.
function AJAXComboBox1_Change() {
//Add event to ui_ddlStrategicObjective AJAX Combobox:
$find('<%=AJAXComboBox1.ClientID %>').add_propertyChanged(function (sender, e) {
if (e.get_propertyName() == 'selectedIndex') {
//Gets the selected index from the HiddenField associated with the AJAX Combobox control.
var selectedIndex = sender.get_hiddenFieldControl().value;
////Gets the selected text from the AJAX ComboBox
var selectedText = sender.get_textBoxControl().value;

//Just sample JS code - you could do anything here:
//show/hide controls, alerts, change client settings, etc.
if (sender.value = 1) {
alert('You selected Red!');
}
else if (sender.value = 2) {
alert('You selected White!');
}
else if (sender.value = 3) {
alert('You selected Blue!');
}
}
});

//AJAX's pageLoad function automatically provides a handler for the 'load' event
function pageLoad() {
//Make call to handle selection changes to the 'AJAXComboBox1' AJAX Combo Box
AJAXComboBox1_Change()
}
Take notice above how we call our new function 'AJAXComboBox1_Change' in pageLoad(). You cannot interact with a control until it has been initialized (i.e. you cannot call add_propertyChanged on a control unless the control actually exists). A control does not exist until the initialization phase of the ASP.NET AJAX framework is complete. We can use AJAX's 'pageLoad()' method as this script needs to be ran during postbacks and partial postbacks is using UpdatePanels. The pageLoad function automatically provides a handler for the 'load' event. You can read about AJAX Client Events in the link below.

ASP.NET AJAX Client Life-Cycle Events

In conclusion there are a few 'big picture' points to make about this entry. First and foremost, when doing web development, try and make your applications as efficient as possible by doing operations client side that don't need to be done on the server (even if they can be done that way).

Second, the AJAX ComboBox may not be a widely used control going forward because its main draw which is the JS support for typing in values and quickly selecting them has been superseded in my opinion by things like the jQuery AutoComplete extender. Dropdowns in general are probably a good choice for the 1-25ish item range, but anything more bloats the page size. In this case making async callbacks to get values real time (like with the jQuery autocomplete) is a better idea. However, it does not mean there aren't a ton of apps already using the AJAX ComboBox, and the need to interact with it client side may present itself someday. If this 'someday' comes up (which it usually does), you will now be prepared to capture its values in JavaScript.