Active Directory Federation Services v2

clock May 6, 2010 07:44 by author jamesstill
ADFS is based on Web Services architecture (WS-* specifications) and conforms to industry standards and protocols. This release supports Azure and would be a great choice for enterprises using AD as a credential store on the local domain who want to migrate to the cloud. Applications hosted on local IIS7 servers as well as in the Azure cloud can take advantage of single sign on over the extranet for the duration of the user's browser session. See MSDN for developing federation-aware applications.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


IIS 7 Errors

clock April 16, 2010 06:07 by author jamesstill

On my sandbox (WinOS 2008) I installed Web Platform Installer 2.0. Then through the PI I installed Frameworks and Runtime (.NET Framework 4.0), IIS 7, and Web Deploy Tool 1.1. I took a vanilla ASP.NET app from the new VS2010 project template and deployed to IIS 7 using the new packaging tools. Depending upon whether the app pool was integrated pipeline or classic I got these errors:

HTTP 404.17: The requested content appears to be script and will not be served by the static file handler.

HTTP 500.21: Handler "PageHandlerFactory-Integrated" has a bad module "ManagedPipelineHandler" in its module list

After corresponding with some devs at Microsoft, they thought there might be a bug in the PI. I ran the following and the problem was fixed: 

C:\Windows\Microsoft.NET\Framework\v4.0.30319>aspnet_regiis.exe -iru -enable

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Lambda Expressions with NHibernate.Linq

clock February 19, 2010 07:33 by author jamesstill

In the last two posts below I talked about creating a templated DataService class and also mused about whether UI data queries really were a cross-cutting concern. I'm agnostic about the question really; however, I do have one practical concern. I don't want to expose methods that take any old HQL query that the client sends my way. I'd like to have a controlled way of extending database queries down to the UI.

The answer is LINQ. Thanks to Rahien and others NHibernate.Linq 1.0 RTM is available. (Eventually this will be merged into the NHibernate mainline but for now it's a separate download.) Once you reference the assembly and put a reference to NHibernate.Linq the extension methods are available in your ISession instance:

   1:  // grab an ISession from ISessionFactory            
   2:  var query = from item in session.Linq()                 
   3:              select item;

So I'm going to extend my DataService class below to support LINQ queries along these lines. Kudos to Ryan Lanciaux who blogged on this before me. To support Linq queries we first must modify the IDataService interface to support lamdba expressions:
   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Linq.Expressions;
   5:  using System.Text;
   6:   
   7:  namespace ConcertMusic.DomainModel
   8:  {
   9:      public interface IDataService<T>
  10:      {
  11:          T Get(int id);
  12:          IList<T> Get(string hqlQueryString);
  13:          IList<T> Get();
  14:          void AddCriteria(Expression<Func<T, bool>> lambdaFunction);
  15:          T Save(T item);
  16:          bool Delete(T item);       
  17:      }
  18:  }

Now to implement the interface in the DataService class:

   1:  public class DataService<T> : IDataService<T>
   2:      {
   3:          private IList<Expression<Func<T, bool>>> _criteria; 
   4:   
   5:          public DataService() 
   6:          {
   7:             _criteria = new List<Expression<Func<T, bool>>>(); 
   8:          }
   9:   
  10:          public void AddCriteria(Expression<Func<T, bool>> lambdaFunction)
  11:          {
  12:              _criteria.Add(lambdaFunction);
  13:          } 
  14:   
  15:          public IList<T> Get()
  16:          {
  17:              using (ISession session = NHibernateHelper.OpenSession())
  18:              {
  19:                  var query = from item in session.Linq<T>()
  20:                              select item;
  21:   
  22:                  foreach (var criterion in _criteria)
  23:                  {
  24:                      query = query.Where<T>(criterion);
  25:                  }
  26:                  return query.ToList(); 
  27:              }         
  28:          }
  29:   
  30:          // other methods removed for clarity
  31:      }
  32:  }

That's pretty much it for the data access plumbing. Now the client code can fetch the IDataService instance and get back anything it wants using lambda expressions. Let's say I want to get every widget from the database with a name that starts with the letter "V". Here's my code:

   1:  IDataService<Widget> svc = DataServiceFactory<Widget>.Create();
   2:  svc.AddCriteria(item => item.Name.StartsWith("V"));
   3:  IList<Widget> list = svc.Get();

And these lambda expressions can be chained of course for very fine-grained search criteria. Suppose I want every widget with a name that starts with the letter "V", is round and blue, and has greater than 8 teeth:

   1:  IDataService<Widget> svc = DataServiceFactory<Widget>.Create();
   2:  svc.AddCriteria(item => item.Name.StartsWith("V"));
   3:  svc.AddCriteria(item => item.Color.Equals("Blue"));
   4:  svc.AddCriteria(item => item.Shape.Equals("Round"));
   5:  svc.AddCriteria(item => item.Teeth > 8));
   6:  IList<Widget> list = svc.Get();

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


UI Data Query A Cross Cutting Concern?

clock February 8, 2010 04:42 by author jamesstill

Rehein makes the interesting argument that there is no clean separation between the presentation, business, and data access layer. Instead, UI concerns often known only at runtime like paging, filtering, sorting, and so on make data querying a cross cutting concern. He therefore, recommends we stop creating UI interfaces like:

    GetInvoicesForUser(int userID)

This is too inflexible and we end up breaking or overloading these interface methods every time a new need comes up:

    GetInvoicesForUser(int userID, int pageNumber, string orderByColumn)

The goal is for any interface implementation to be open for extension but closed for modification. But by insisting upon a hard separation of concern between the UI and the business/facade interface we're making modifications left and right.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Refactor to DataService

clock February 1, 2010 15:23 by author jamesstill

In the post below on NHibernate 101 I said not to plumb data access code in the Operation Contract implementation. Now I'd like to refactor and get that out of there. Let's think about it a bit first. Do I really want to create a data layer class called "InstrumentService" with the CRUD in there? I could. But since this is a concert music application, I know I'm going to have several lookup tables in the system. In addition to musical instruments there will be musical genres, catalogs, recording labels, ensemble types, and so on and on.

So we want to make sure all of these data access classes implement an interface with the standard read, insert, update, and delete behavior. Let's do it. But let's be smart about it and take advantage of generics:

   1:  public interface IDataService<T>
   2:  {
   3:      IList<T> GetAll(string queryString);
   4:      T GetItem(int id);
   5:      T Save(T item);
   6:      bool Delete(int id, string tableName);
   7:      bool Delete(T item);
   8:  }

Having done that we can code a single DataService that implements the interface:

   1:  /// <summary>
   2:  /// Data service to fetch and save common lookup table items.
   3:  /// </summary>
   4:  public class DataService<T> : IDataService<T>
   5:  {
   6:      public DataService() { }
   7:   
   8:      public IList<T> GetAll(string queryString)
   9:      {
  10:          IList<T> list;
  11:          using (ISession session = NHibernateHelper.OpenSession())
  12:          {
  13:              IQuery query = session.CreateQuery(queryString);
  14:              list = query.List<T>();
  15:          }
  16:          return list;
  17:      }
  18:   
  19:   
  20:      public T GetItem(int id)
  21:      {
  22:          T item;
  23:          using (ISession session = NHibernateHelper.OpenSession())
  24:          {
  25:              item = session.Get<T>(id);
  26:          }
  27:          return item;
  28:      }
  29:   
  30:   
  31:      public T Save(T item)
  32:      {
  33:          using (ISession session = NHibernateHelper.OpenSession())
  34:          {
  35:              using (ITransaction transaction = session.BeginTransaction())
  36:              {
  37:                  session.SaveOrUpdate(item);
  38:                  transaction.Commit();
  39:              }
  40:          }
  41:          return item;
  42:      }
  43:   
  44:   
  45:      public bool Delete(int id, string tableName)
  46:      {
  47:          bool deleted = false;
  48:          using (ISession session = NHibernateHelper.OpenSession())
  49:          {
  50:              using (ITransaction transaction = session.BeginTransaction())
  51:              {
  52:                  string hqlString = string.Format("from {0} where ID = :ID", tableName);
  53:                  session.Delete(hqlString, id, NHibernateUtil.Int32);
  54:                  transaction.Commit();
  55:                  deleted = true;
  56:              }
  57:          }
  58:          return deleted;
  59:      }
  60:   
  61:      public bool Delete(T item)
  62:      {
  63:          bool deleted = false;
  64:          using (ISession session = NHibernateHelper.OpenSession())
  65:          {
  66:              using (ITransaction transaction = session.BeginTransaction())
  67:              {
  68:                  session.Delete(item);
  69:                  transaction.Commit();
  70:                  deleted = true;
  71:              }
  72:          }
  73:          return deleted;
  74:      }
  75:  }

Note that this implementation assumes that all of my lookup tables will have a surrogate primary key. There's just one last detail and that's creating a factory for these DataService instances. It's not really necessary. But I'm obsessed with web service methods that do as little as possible so I'm going to make their job as easy as possible. So here's the simple factory:

   1:  public class DataServiceFactory<T> where T : new()
   2:  {
   3:      public static DataService<T> Create()
   4:      {
   5:          return new DataService<T>();
   6:      }
   7:  }

That takes care of the NHiberate plumbing for all lookup tables in my system. Now if I want to fetch all musical instruments, or genres, or record labels from the system it's pretty easy:

   1:  public IList<Instrument> GetInstruments()
   2:  {
   3:      IDataService<Instrument> svc = DataServiceFactory<Instrument>.Create();
   4:      return svc.GetAll("FROM Instrument");
   5:  }
   6:   
   7:  public IList<Genre> GetGenres()
   8:  {
   9:      IDataService<Genre> svc = DataServiceFactory<Genre>.Create();
  10:      return svc.GetAll("FROM Genre");
  11:  }
  12:   
  13:  public IList<Catalog> GetCatalogs()
  14:  {
  15:      IDataService<Catalog> svc = DataServiceFactory<Catalog>.Create();
  16:      return svc.GetAll("FROM Catalog");
  17:  }

The one thing that still bugs me is the hard-coded "FROM [TableName]" that gets passed in. That could get refactored and put into the DataService base class. However, doing so would make an assumption that I'm not ready to make, namely, that my class name equals the table name. There is probably a way to decorate the POCO classes with attributes but then we're creeping back into domain entites that are not persistent ignorant. So it's a small price to pay.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


NHibernate 101: Silverlight 4 with NHibernate 2.n

clock February 1, 2010 05:44 by author jamesstill

In this intro I'll create a vanilla Silverlight 4 application, hosted in a WCF Service, and wired up to SQL Server 2008 with the open source NHibernate ORM tool. I'm not going to dive into the weeds here. I just want to show the basics.

Prerequisites:

* Visual Studio 2010 Beta 2
* Silverlight 4 Tools for VS 2010
* NHibernate 2.n
* SQL Server 2008

In Visual Studio create a new project using the Silverlight Application project template. When prompted, choose to host the project in a new web site with the default ASP.NET Web Application Project type. I'll call it "ConcertMusic.Web" because we're going to fetch a list of classical music instruments from a database table and display them in a SL DataGrid. Do not enable .NET RIA Services.

After the project template unfolds right-click the ConcertMusic.Web and create a WCF Service using the Silverlight-enabled WCF Service template. I'm not going to get into WCF here but you'll want to create a contract interface, configure the service behavior and bindings, and perhaps add a ClientAccessPolicy.xml file. Here's my service contract:

   1:  namespace ConcertMusic.Web
   2:  {
   3:      [ServiceContract(Namespace="http://ConcertMusic.Web/2010/07")]
   4:      public interface IConcertMusicService
   5:      {
   6:          [OperationContract]
   7:          IList<Instrument> GetInstruments();
   8:      }
   9:  }

Now let's configure NHiberate. Add references to the required NHibernate assemblies: NHibernate.dll, log4net.dll, Iesi.collections.dll, and Antlr3.Runtime.dll. (Optionally, include Castle or Spring assemblies if you want to support lazy loading. I'm not going to get into that here.)

In Web.config add the plumbing to configure NHibernate:

   1:  <configuration>
   2:   
   3:    <configSections>
   4:      <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
   5:    </configSections>
   6:   
   7:    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
   8:      <session-factory>
   9:        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
  10:        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
  11:        <property name="connection.connection_string">Data Source=SERVER_INSTANCE;Initial Catalog=DatabaseName;Integrated Security=SSPI</property>
  12:        <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
  13:        <property name="show_sql">false</property>
  14:        <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
  15:      </session-factory>
  16:    </hibernate-configuration>

Ok so we've got the NHibernate assemblies referenced and we've configured it the project. Let's start at the database and work our way forward. First, we've got a table of musical instruments in the database:

   1:  CREATE TABLE [dbo].[Instrument](
   2:      [ID] [int] IDENTITY(1,1) NOT NULL,
   3:      [Name] [nvarchar](50) NULL,
   4:      [Description] [nvarchar](120) NULL,
   5:   CONSTRAINT [PK_Instrument] PRIMARY KEY CLUSTERED 
   6:  (
   7:      [ID] ASC
   8:  )WITH 
   9:  (PAD_INDEX  = OFF, 
  10:  STATISTICS_NORECOMPUTE  = OFF, 
  11:  IGNORE_DUP_KEY = OFF, 
  12:  ALLOW_ROW_LOCKS  = ON, 
  13:  ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  14:  ) ON [PRIMARY]
  15:   
  16:  GO

We need to do two things to map the table to a plain old CLR object (POCO) in our application. We have to create the POCO class and then we have to create a mappping file that tells NHibernate how to create an instance of that class from the data store. Here's our simple POCO class:

   1:  [DataContract]
   2:  public class Instrument
   3:  {
   4:      public Instrument() { }
   5:   
   6:      [DataMember]
   7:      public virtual int ID { get; set; }
   8:   
   9:      [DataMember]
  10:      public virtual string Name { get; set; }
  11:   
  12:      [DataMember]
  13:      public virtual string Description { get; set; }
  14:  }

Notice that we're using auto-implemented properties introduced in C# 3.0. Also, the class is implemented as a DataContract with DataMember properties. This is necessary if you want to bind an IList collection of Instrument objects to a Silverlight control. If you don't use DataMember attributes, then Silverlight will attempt to bind to the IL-generated backing fields instead and you'll get skinny blank rows in your DataGrid.

Ok, now let's create the NHibernate mapping file. It can live in the same place as the POCO or you can put your mapping files in a separate folder to keep them all together. It's up to you. The naming convention is [ClassName].hbm.xml:

   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <hibernate-mapping assembly="ConcertMusic.Web" xmlns="urn:nhibernate-mapping-2.2">
   3:    <class name="ConcertMusic.DomainModel.Instrument, ConcertMusic.DomainModel" table="Instrument" lazy="false" >
   4:      <id name="ID" type="Int32" column="ID">
   5:        <generator class="identity" />
   6:      </id>
   7:      <property name="Name" column="Name" />
   8:      <property name="Description" column="Description" />
   9:    </class>
  10:  </hibernate-mapping>

I'm not going into a long explanation of this file. Read the NHibernate docs for a detailed specification. For now I'll just say that ID is described as a synthetic key (identity column), and Name and Description are mapped one-to-one to identical column names in the table. Pretty straightforward. Very important! Change the build action of this xml file to make it an embedded resource. It needs to be compiled into the assembly in order by NHibernate to find it at runtime.

NHibernate uses an ISessionFactory to talk to the database. Just like IDbConnections in ADO.NET, these are very expensive to set up so you don't want to set them up and tear them down with every transaction to the database. The best practice is to create them once and then hold onto them during the lifetime of the application. Here I'm using a Singleton pattern to wrap the factory in a helper class:

   1:  public class NHibernateHelper
   2:  {
   3:      public static readonly ISessionFactory SessionFactory;
   4:   
   5:      static NHibernateHelper()
   6:      {
   7:          Configuration cfg = new Configuration().AddAssembly("ConcertMusic.DomainModel");
   8:          SessionFactory = cfg.Configure().BuildSessionFactory();
   9:      }
  10:   
  11:      public static ISession OpenSession()
  12:      {
  13:          return SessionFactory.OpenSession();
  14:      }
  15:  }

In line 7 I'm adding the assembly ConcertMusic.DomainModel to the NHibernate configuration. This is to tell NHibernate where my [ClassName].hbm.xml mapping files live. I created a separate project for my POCO classes and NHibernate mapping files. Change this to Silverlight1.Web or whatever assembly name where your mapping files were added.

One last plumbing task to complete. We need to implement the OperationContract so that Silverlight can call and fetch a list of musical instruments. I keep my web methods very thin but for illustration purposes only I'll just code it right there:

   1:  public class ConcertMusicService : IConcertMusicService
   2:  {
   3:      public IList<Instrument> GetInstruments()
   4:      {
   5:          IList<Instrument> list;
   6:          using (ISession session = NHibernateHelper.OpenSession())
   7:          {
   8:              IQuery query = session.CreateQuery("FROM Instrument");
   9:              list = query.List<Instrument>();
  10:          }
  11:          return list;    
  12:      }
  13:  }

Do not do this in a production application. Get that data access plumbing out of your web method and into a data layer somewhere. That makes it easy to write unit tests that call the data layer too. But this is fine for our purposes. Run your unit tests and make sure it's all working. Then wire up the Silverlight MainPage.xaml to consume the data. Drag a DataGrid onto your MainPage.xaml. It should register the System.Windows.Controls.Data assembly and stub out a DataGrid for you:

   1:  <data:DataGrid x:Name="InstrumentDataGrid" AutoGenerateColumns="False" Height="400" Width="200">
   2:      <data:DataGrid.Columns>
   3:          <data:DataGridTextColumn Header="ID" Binding="{Binding ID}" />
   4:          <data:DataGridTextColumn Header="Name" Binding="{Binding Name}" />
   5:      </data:DataGrid.Columns>
   6:  </data:DataGrid>

Create a service reference to the WCF service in your Silverlight app. Then in the code behind make an async call to the web service and bind the results to the grid:

   1:  public partial class MainPage : UserControl
   2:  {
   3:      public MainPage()
   4:      {
   5:          InitializeComponent();
   6:          Loaded += new RoutedEventHandler(MainPage_Loaded);
   7:      }
   8:   
   9:      void MainPage_Loaded(object sender, RoutedEventArgs e)
  10:      {
  11:          ConcertMusicServiceClient service = new ConcertMusicServiceClient();
  12:          service.GetInstrumentsCompleted += 
  13:              new EventHandler<GetInstrumentsCompletedEventArgs>(Service_GetInstrumentsCompleted);
  14:          service.GetInstrumentsAsync();
  15:      }
  16:   
  17:      void Service_GetInstrumentsCompleted(object sender, GetInstrumentsCompletedEventArgs e)
  18:      {
  19:          InstrumentDataGrid.ItemsSource = e.Result;  
  20:      } 
  21:  }

That's all there is to it.

Currently rated 2.0 by 1 people

  • Currently 2/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Mastering WCF RIA Services

clock November 19, 2009 16:10 by author jamesstill

You don't have to use EF with RIA Services. Dinesh Kulkarni demonstrated how to implement a DomainService class using NHibernate.

Kulkarni emphasizes that WCF RIA Services is a prescriptive pattern and that they designed it to be DAL agnostic. Sounds like the Ruby philosophy...

For your DomainService implementation you can add an attribute for an update method to declaritively require that the user be in a certain role:

[RequiresAuthentication]
[RequiresRole("Administrator")]
public void UpdateFoo(SomeEntity entity) {
   
}

This is useful if you want end users to be able to query data without yet logging in but then they have to log in to makes updates.

Best practices to use RIA Services effectively:
 
Do:

* require authentication / roles
* use https in IIS
* utilize query composition (filter, sort, page)
* consider custom update
* factor into multiple DomainService classes and libraries, especially for large apps
* handle errors server-side
* use declarative validation

Don't:

* deploy with anonymous access
* expose non-essential entities/operations
* allow free-form access to data (malicious user problem)
* don't throw everything into one big DomainService class

Unfortunately we ran out of time and he was unable to demonstrate the NHibernate plumbing.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Brad Abrams on RIA Services with EF

clock November 19, 2009 06:26 by author jamesstill

Abrams basically walked through a typical RIA Services app and most of it is familiar to anyone who has studied the RIA Services documentation and walkthrough. However there were several new things specific to VS2010 and the new bits.

RIA Services is now built on top of WCF. Yep, it's a first-class citizen on the stack right next to Workflow Services and Data Services. Brad Abrams said his goal with RIA was to force n-tier dev and to get people into the 21st century. :) That's why (and I'm translating here, he didn't say this) RIA is a prescriptive framework following the 80/20 rule rather than something totally open ended like the vanilla ASP.NET web project template.

The project template is now out of the box in VS2010/.NET 4.0. Also, there's a design view for XAML now. In fact, all the SL controls are on the toolbox and you don't have to edit the XAML at all. My first impulse is one of repulsion -- however, I realize that this is a great time saver for doing a first cut on layout and wiring up controls. You can always go into the XAML and tweak it later.

with a DataGrid and Pager control RIA does not go grab all nn number of rows from the database and bind it to the grid like in early ASP.NET. It takes advantage of LINQ and gets only the rows for the current page. That data is cached locally so if user clicks back arrow to go back to page 1 it's there.

No more XAML exploring. VS2010 has a Document Outline toolbar that shows a visual representation
of the nodes and their hierarchy.

No more rebuilding the RIA Service in order to push the gs file down to the SL client. Changes are reflected right away.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


WCF 4

clock November 19, 2009 06:23 by author jamesstill

You no longer need to describe in detail all of the configuration for endpoints, bindings and protocols. For example, if you wipe out your web.config then basicHttp protocol is used by default. Also, and this is obscure, by default WCF 4 will act as a protocol bridge. If the client request is SOAP 1.1 but the back end service is SOAP 1.2 the bridge will transform the message automatically, which is transparent both to the client and service. In effect then the client can be an old skool app speaking SOAP 1.1 in http and the back end service can be SOAP 1.2 in tcp and no additional endpoints need to be configured. You do need to create a RoutingService to support routing behavior.

Something called "ETW" (also built into Azure AppFabric) is the new direction for instrumentation for IIS, ASP.NET, and WPF as well as apps running in the Azure cloud. For the purposes of WCF 4, it will be possible to instrument the whole call stack and pinpoint exactly which service and contract implementation is the bottleneck.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


VS2010 and MS Deploy

clock November 19, 2009 06:21 by author jamesstill

VS2010 along with the existing project templates for SQL Server 2005/8 will now allow you to configure a complete build package that targets any environment as well as the database. Vishal Joshi did a demo at PDC that was pretty sweet. His blog is http://bit.ly/vijoshi and he has a lot of notes on known issues, release notes, and links to documentation. No longer will it be necessary to get the DBA and the sys admin to coordinate the push to staging or prod.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


About

SquareWidget LLC is an Oregon-based software development company that specializes in handcrafted .NET software solutions.

Search

Archive

Categories


Sign in