Archives

Archives / 2013 / April
  • Querying Entity Framework Code First Inheritance

    This is a short post to complement my previous one on Entity Framework Code First Inheritance: how to query for a specific class. The options are:

    1. From the DbContext collection:
         1: IEnumerable<DerivedA> derived = ctx.Bases.OfType<DerivedA>().ToList();
    2. From the inner ObjectContext, using Entity SQL and the OFTYPE operator:
         1: IEnumerable<DerivedA> derived = (ctx as IObjectContextAdapter).ObjectContext.CreateQuery<DerivedA>("SELECT VAlUE b FROM OFTYPE(Bases, MyNamespace.DerivedA) AS b").OfType<DerivedA>().ToList();
    3. Also in Entity SQL, using TREAT and IS OF:
         1: IEnumerable<DerivedA> derived = (ctx as IObjectContextAdapter).ObjectContext.CreateQuery<DerivedA>("SELECT VAlUE TREAT(b AS MyNamespace.DerivedA) FROM Bases AS b WHERE b IS OF (ConsoleApplication1.DerivedA)").OfType<DerivedA>().ToList();
    4. Using LINQ to Entities:
         1: IEnumerable<DerivedA> derived = (from d in ctx.Bases where d is DerivedA select d as DerivedA).ToList();
    5. Using pure SQL:
         1: IEnumerable<DerivedA> derived = ctx.Database.SqlQuery<DerivedA>("SELECT * FROM Bases AS b WHERE b.Discriminator = 'DerivedA'").ToList();

    Read more...

  • Visual Studio 2012 and .NET 4.5 Expert Development Cookbook Review

    Visual Studio 2012 and .NET 4.5 Expert Development Cookbook

    Visual Studio 2012 and .NET 4.5 Expert Development Cookbook

    I recently started reading Packt Publishing’s Visual Studio 2012 and .NET 4.5 Expert Development Cookbook. It is a book focused primarily on the new features of .NET 4.5 and Visual Studio 2012. Although some concepts already existed in previous versions (some Visual Studio IDE elements, for example), others are quit new (take Windows 8 programming APIs and the new asynchronous syntax). It follows the now classic recipes or cookbook approach, where for each category, a number of recipes are presented with a brief description of their purpose and some code to illustrate the solution. It is a very focused book, it doesn’t cover anything that shouldn’t be there.

    The first chapter is about the IDE, how to use it effectively and how to extend it without using code. It walks us through creating templates and code snippets and in the process we get to know smart tags, refactoring options, UML diagrams and other nice functionality.

    On second chapter, the focus is .NET application and memory management. We learn about the internal structure of a .NET assembly (actually, its various types), garbage collection and memory management and even how to disassemble it with ILMerge or Reflector. Talking about disassembling, some tips for protecting an assembly against it are also presented by means of Dotfuscator. Also includes an interesting tip on detecting memory leaks. This is the one chapter that mostly deals with pre-.NET 4.5 concepts.

    Next comes asynchronous programming, something that most people (including myself) are looking with increased interest since the arrival of .NET 4.5. The chapter presents all programming models currently available for .NET developers and talks about some not well known thread synchronization objects and techniques of the .NET world, including guidelines on choosing the appropriate mechanisms. Finally it covers the new async and await pattern.

    Following is a chapter on the new enhancements to ASP.NET, which go from HTML5 editor and syntax support to working with strongly-typed models in data-bound controls. In the middle, it also covers using asynchronous programming techniques in pages, modules and handlers and effectively using jQuery. There’s also a recipe on actually using some of HTML5’s new features, which is not strictly on ASP.NET, but is useful nevertheless.

    WPF is next. The very popular MVVM patter is presented together with the new improvements like Ribbon support, a feature which seems to be becoming ubiquitous in Microsoft products.

    The final chapters are all about Windows 8 applications. The first focuses on building touch-sensitive applications. It was a fun read, because I knew absolutely nothing on the subject. It actually covers more than just touch-sensitive applications, and covers WinRT, JavaScript and XAML.

    The last chapter talks about the various options for communicating and sharing contained within Windows 8. Also a very interesting one, of which I knew nothing about. It covers the ways by which we can share data between Windows 8 applications, writing notification services in WCF and displaying notifications in tiles or toasts.

    It was a very pleasant read, I am sure to return to it very often, for some of the topics are very wide.

    Read more...

  • Entity Framework Code First Inheritance

    Introduction

    Another post for self reference, this time, how to map inheritance strategies with Entity Framework Code First.

    Single Table Inheritance / Table Per Class Hierarchy

    First, the default strategy: one table for all classes in the hierarchy. Will store all columns on the same table, so all properties on derived classes must be nullable, and there will be lots of nulls. An additional column will be created, which will contain a discriminator value for deciding which type corresponds to each row.

       1: [Table("Base")]
       2: public abstract class Base
       3: {
       4:     public Int32 BaseId { get; set; }
       5:  
       6:     public String InheritedColumn { get; set; }
       7: }

     

       1: public class DerivedA : Base
       2: {
       3:     public String A { get; set; }
       4: }

     

       1: public class DerivedB : Base
       2: {
       3:     public String B { get; set; }
       4: }

     

    image

     

    Class Table Inheritance / Table Per Type

    This will map all properties of the base class into a table of its own and each derived class in its own table, connected to the base table by a foreign key. No duplication will occur and properties on derived classes can be mapped as not nullable.

       1: [Table("Base")]
       2: public abstract class Base
       3: {
       4:     public Int32 BaseId { get; set; }
       5:  
       6:     public String InheritedColumn { get; set; }
       7: }

     

       1: [Table("DerivedA")]
       2: public class DerivedA : Base
       3: {
       4:     public String ColumnA { get; set; }
       5: }

     

       1: [Table("DerivedB")]
       2: public class DerivedB : Base
       3: {
       4:     public String ColumnB { get; set; }
       5: }

     

    image

     

    Concrete Table Inheritance / Table Per Concrete Type

    No table for the base class, each concrete class will have its own table, which will contain columns for all of the class’ properties, including inherited ones. One record will only exist in one of the tables, so usage of IDENTITY columns as primary keys is not possible, because there will be records with the same ID on all of the tables, unless different seeds and/or increments are used.

       1: public abstract class Base
       2: {
       3:     public Int32 BaseId { get; set; }
       4:  
       5:     public String InheritedColumn { get; set; }
       6: }

     

       1: [Table("DerivedA")]
       2: public class DerivedA : Base
       3: {
       4:     public String ColumnA { get; set; }
       5: }

     

       1: [Table("DerivedB")]
       2: public class DerivedB : Base
       3: {
       4:     public String ColumnB { get; set; }
       5: }

    This will require additional configuration at the context level, this strategy is not possible just with attributes:

       1: public class Context : DbContext
       2: {
       3:     protected override void OnModelCreating(DbModelBuilder modelBuilder)
       4:     {
       5:         modelBuilder.Entity<DerivedA>().Map(m =>
       6:         {
       7:             m.MapInheritedProperties();
       8:         });
       9:         modelBuilder.Entity<DerivedB>().Map(m =>
      10:         {
      11:             m.MapInheritedProperties();
      12:         });
      13:     }
      14:  
      15:     public DbSet<Base> Bases { get; set; }
      16: }

     

    image

    Read more...

  • Entity Framework Code First Relations

    Introduction

    This post is more for self-reference than anything else. Basically, I tend to forget some options for mapping relations with Entity Framework Code First, so I wrote this. If in doing so it helps someone, even better! Winking smile

    One-to-Many

    First, the most basic: one-to-many/many-to-one: an instance of the Master class has lots of Details.

       1: public class Master
       2: {
       3:     public Int32 MasterId { get; set; }
       4:  
       5:     public virtual ICollection<Detail> Details { get; protected set; }
       6: }

     

       1: public class Detail
       2: {
       3:     public Int32 DetailId { get; set; }
       4:  
       5:     public virtual Master Master { get; set; }
       6: }

    image

    One-to-One

    The stepchild of database relations. Sometimes it is useful, though: a single Master has an optional Detail, which always refers to an existing Master.

       1: public class Master
       2: {
       3:     public Int32 MasterId { get; set; }
       4:  
       5:     public virtual Detail Detail { get; set; }
       6: }

     

       1: public class Detail
       2: {
       3:     [Key]
       4:     [ForeignKey("Master")]
       5:     public Int32 MasterId { get; set; }
       6:  
       7:     [Required]
       8:     public virtual Master Master { get; set; }
       9: }

    image

    Many-to-Many

    A single Master can have many Details; each Detail can itself be connected to multiple Masters.

       1: public class Master
       2: {
       3:     public Master()
       4:     {
       5:         this.Details = new List<Detail>();
       6:     }
       7:  
       8:     public Int32 MasterId { get; set; }
       9:  
      10:     public virtual ICollection<Detail> Details { get; protected set; }
      11: }

     

       1: public class Detail
       2: {
       3:     public Detail()
       4:     {
       5:         this.Masters = new List<Master>();
       6:     }
       7:  
       8:     public Int32 DetailId { get; set; }
       9:  
      10:     public virtual ICollection<Master> Masters { get; protected set; }
      11: }

    image

    One-to-Many With Composite Key

    In this case we have a composite primary key constituted by a foreign key and a scalar column: a Master instance is related with many Details and each Detail is identified by both a single Master and a timestamp.

       1: public class Master
       2: {
       3:     public Master()
       4:     {
       5:         this.Details = new List<Detail>();
       6:     }
       7:  
       8:     public Int32 MasterId { get; set; }
       9:  
      10:     public virtual ICollection<Detail> Details { get; protected set; }
      11: }

     

       1: public class Detail
       2: {
       3:     [Key]
       4:     [ForeignKey("Master")]
       5:     [Column(Order = 0)]
       6:     public Int32 MasterId { get; set; }
       7:  
       8:     [Required]
       9:     public virtual Master Master { get; set; }
      10:  
      11:     [Key]
      12:     [Column(Order = 1)]
      13:     public DateTime Timestamp { get; set; }
      14: }

    image

    Have I forgotten something? Let me know!

    Read more...

  • Unity – Part 3: Aspect Oriented Programming

    AOP

    This is my third post on Unity. See the first here for an introduction and the second here for how to apply dependency injection.

    Aspect Oriented Programming (AOP) is a technique for applying cross-cutting concerns to existing implementations, without modifying them. Some examples of it are:

    • Wrapping method calls that go to the database in transactions automatically;
    • Logging all calls to some method, including the input parameters and return value;
    • Catching exceptions thrown in a method automatically and doing something with them.

    AOP is supported in the Enterprise Library (of which Unity is part) by the Policy Injection application block, and it can be integrated with Unity. You must install this application block, perhaps by using NuGet:

    image

    We need to add the interception behavior – which is the one that actually applies aspects – to Unity, either by code:

       1: unity.AddNewExtension<Interception>();

    Or by XML configuration:

       1: <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
       2:     <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>
       3: </unity>

    Having said that, the first concept we need to know is that of an interceptor. An interceptor in the Policy Injection block is an implementation of Microsoft.Practices.Unity.InterceptionExtension.IInterceptor interface, and there are three implementations:

    It is required that, when you are going to apply an aspect to a registration, you choose an interceptor suitable for that registration, based on what type we are registering.

    An aspect itself is an implementation of Microsoft.Practices.Unity.InterceptionExtension.ICallHandler, Unity includes five out of the box such handlers:

    The ICallHandler interface only defines a single method, Invoke, which wraps a method’s arguments and allows having code run before, after or even instead of the target method, and an Order property, for specifying the order by which the aspect should be applied, in case there are many.

    A simple call handler, for outputting some string before or after a method call, might be:

       1: public class OutputCallHandler : ICallHandler
       2: {
       3:     public Boolean Before
       4:     {
       5:         get;
       6:         set;
       7:     }
       8:  
       9:     public Boolean After
      10:     {
      11:         get;
      12:         set;
      13:     }
      14:  
      15:     public String Message
      16:     {
      17:         get;
      18:         set;
      19:     }
      20:  
      21:     Int32 ICallHandler.Order
      22:     {
      23:         get;
      24:         set;
      25:     }
      26:  
      27:     IMethodReturn ICallHandler.Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
      28:     {
      29:         if (this.Before == true)
      30:         {
      31:             Console.WriteLine(this.Message);
      32:         }
      33:  
      34:         IMethodReturn result = getNext()(input, getNext);
      35:  
      36:         if (result.Exception != null)
      37:         {
      38:             Console.Error.WriteLine(result.Exception.Message);
      39:         }
      40:         else
      41:         {
      42:             if (this.After == true)
      43:             {
      44:                 Console.WriteLine(this.Message);
      45:             }
      46:         }
      47:  
      48:         return (result);
      49:     }
      50: }

    Another option is to have interception for all methods of the target registration, which can be achieved by implementing Microsoft.Practices.Unity.InterceptionExtension.IInterceptionBehavior in a concrete class, such as this:

       1: public class MyInterceptionBehavior : IInterceptionBehavior
       2: {
       3:     IEnumerable<Type> IInterceptionBehavior.GetRequiredInterfaces()
       4:     {
       5:         return (Type.EmptyTypes);
       6:     }
       7:  
       8:     IMethodReturn IInterceptionBehavior.Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
       9:     {
      10:         //before target method call
      11:  
      12:         if (input.MethodBase == typeof(MyService).GetMethod("DoSomething"))
      13:         {
      14:             //do something
      15:         }
      16:  
      17:         IMethodReturn methodReturn = getNext().Invoke(input, getNext);
      18:  
      19:         //after target method call
      20:  
      21:         return (methodReturn);
      22:     }
      23:  
      24:     Boolean IInterceptionBehavior.WillExecute
      25:     {
      26:         get
      27:         {
      28:             return (true);
      29:         }
      30:     }
      31: }

    If we want to cancel the default method call, if it is non void, we must return an appropriate value:

       1: IMethodReturn methodReturn = input.CreateMethodReturn(someValue, input.Arguments);

    Or if we want to return an exception:

       1: IMethodReturn methodReturn = input.CreateExceptionMethodReturn(new SomeException());

    There are three ways by which we can apply an aspect to a registration:

    • By applying an attribute to a method on the declaring or target type;
    • By code configuration;
    • By XML configuration.

    Interception By Attributes

    We need to create an attribute that derives from Microsoft.Practices.Unity.InterceptionExtension.HandlerAttribute and which instantiates our call handler:

       1: [Serializable]
       2: [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
       3: public sealed class OutputCallHandlerAttribute : HandlerAttribute
       4: {
       5:     public Boolean Before
       6:     {
       7:         get;
       8:         set;
       9:     }
      10:  
      11:     public Boolean After
      12:     {
      13:         get;
      14:         set;
      15:     }
      16:  
      17:     public String Message
      18:     {
      19:         get;
      20:         private set;
      21:     }
      22:  
      23:     public OutputCallHandlerAttribute(String message)
      24:     {
      25:         this.Message = message;
      26:     }
      27:  
      28:     public override ICallHandler CreateHandler(IUnityContainer container)
      29:     {
      30:         return (new OutputCallHandler() { After = this.After, Before = this.Before, Message = this.Message });
      31:     }        
      32: }

    And we apply it to any method declaration:

       1: public interface IMyService
       2: {
       3:     [OutputCallHandler("Before", Before = true)]
       4:     [OutputCallHandler("After", After = true)]
       5:     void DoSomething();
       6: }

    But before this works, we need to tell Unity to use interface interception for our type:

       1: unity.Configure<Interception>().SetDefaultInterceptorFor<IMyService>(new InterfaceInterceptor());

    Interception By Code

    For intercepting by code, whenever we register something with Unity, we also tell it to use interface interception and to include a behavior instance – it is not possible to specify a call handler for a specific method:

       1: unity.RegisterType<IMyService, MyService>(new ContainerControlledLifetimeManager(), new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<OutputInterceptionBehavior>());

    Interception By Configuration

    When applying interception by configuration we also cannot target a specific method, but instead specify an interception behavior, which will apply to all method – of course, inside of it we can do our own filtering, by looking at the IMethodInvocation.MethodBase property:

       1: <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
       2:     <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>
       3:     <container>
       4:         <extension type="Microsoft.Practices.Unity.InterceptionExtension.Interception, Microsoft.Practices.Unity.Interception"/>
       5:         <interceptors>
       6:             <interceptor type="InterfaceInterceptor">
       7:                 <default type="MyNamespace.IMyService, MyAssembly"/>
       8:             </interceptor>
       9:         </interceptors>
      10:         <register type="MyNamespace.IMyService, MyAssembly" mapTo="MyNamespace.MyService, MyAssembly">
      11:             <lifetime type="singleton"/>
      12:             <interceptionBehavior type="MyNamespace.OutputInterceptionBehavior, MyAssembly"/>
      13:         </register>
      14:         </register>
      15:     </container>
      16: </unity>

    Executing

    You must Unity to retrieve an instance, which will be properly wrapped in a proxy, and from there all of your configured interceptors will be called:

       1: IMyService svc = ServiceLocator.Current.GetInstance<IMyService>();
       2: svc.DoSomething();

    Next in line: extending Unity.

    Read more...

  • Unity – Part 2: Dependency Injection

    Dependency Injection

    Second part of my series on Unity. For an introduction, read the first post.

    OK, now we know how to get Inversion of Control (IoC): instead of referencing a particular concrete implementation, we instead reference an interface or an abstract base class, which creates a level of abstraction and allows us to change things at a later time.

    Now let’s see what Unity has to offer in terms of Dependency Injection (DI). DI is the process by which objects are populated (injected) with values, called dependencies, usually coming from the IoC container itself. Basically, we have three options for that:

    • Constructor injection;
    • Property injection;
    • Method injection.

    What this means is, when asked for a particular instance, Unity will call a constructor, set a property’s value or invoke a method with a parameter coming from its registration. Say you have a class like this:

       1: public class MyService : IMyService
       2: {
       3:     public ILogger Logger
       4:     {
       5:         get;
       6:         private set;
       7:     }
       8:  
       9:     public MyService(ILogger logger)
      10:     {
      11:         this.Logger = logger;
      12:     }
      13:  
      14:     public void SetLogger(ILogger logger)
      15:     {
      16:         this.Logger = logger;
      17:     }
      18: }

    Unity can inject the Logger instance by either passing a parameter on the constructor when building an instance of the MyService class, directly setting the Logger property (even with a private setter) or by invoking the SetLogger method.

    Injection By Configuration

    As we have seen, most things in Unity can be configured by XML configuration:

       1: <register type="MyNamespace.IMyService, MyAssembly" mapTo="MyNamespace.MyService, MyAssembly">
       2:     <constructor>
       3:         <param name="logger" dependencyType="MyNamespace.ILogger, MyAssembly" dependencyName="File"/>
       4:     </constructor>
       5:     <property name="Logger" dependencyType="MyNamespace.ILogger, MyAssembly" dependencyName="File"/>
       6:     <method name="SetLogger">
       7:         <param name="logger" dependencyType="MyNamespace.ILogger, MyAssembly" dependencyName="File"/>
       8:     </method>
       9: </register>

    Did you notice the dependencyName attribute? That is the name under which the dependencyType was registered, if not set, it defaults to the empty string.

    I have included both constructor, property and method injection, you usually will only need one of them.

    Injection By Code

    Another option is by code. When registering a type, you must add some additional code:

       1: unity.RegisterType<IMyService, MyService>(new InjectionConstructor(unity.Resolve<ILogger>("File")), new InjectionMethod("SetLogger", unity.Resolve<ILogger>("File")), new InjectionProperty("Logger", unity.Resolve<ILogger>("File")));

    If you don’t want to resolve an instance yourself in InjectionMethod, InjectionConstructor or InjectionProperty, you can pass a Type and Unity will look up the actual instance for you.

    Injection By Attributes

    Another option is by applying attributes:

       1: public class MyService : IMyService
       2: {
       3:     [Dependency("File")]
       4:     public ILogger Logger
       5:     {
       6:         get;
       7:         private set;
       8:     }
       9:  
      10:     [InjectionConstructor]
      11:     public MyService([Dependency("File")] ILogger logger)
      12:     {
      13:         this.Logger = logger;
      14:     }
      15:  
      16:     [InjectionMethod]
      17:     public void SetLogger([Dependency("File")] ILogger logger)
      18:     {
      19:         this.Logger = logger;
      20:     }
      21: }

    The File string is the name of the registered type.

    Like previously mentioned, although I depicted all three, you will pick only one injection method. When you call Resolve or GetInstance, the instance you get will have its dependencies assigned.

    Injecting Dependencies On Existing Entities

    If you have some object instance that was obtained elsewhere, you can still ask Unity to inject whatever dependencies this object has. This is achieved by the BuildUp family of methods:

       1: IMyService svc = new MyService();
       2:  
       3: unity.BuildUp(svc);    //Logger property is set and SetLogger method is called

    Next in line: applying aspects. Stay tuned!

    Read more...

  • Extended ASP.NET Button Control

    I once had the need to have a button control that would change its look depending on a theme, for example, it would render either as regular button, an image or a link. Of course, the only way I had to achieve this was by manually swapping the Button control for a ImageButton or a LinkButton, which wasn’t really a solution, so I started to think of a control that could do the trick… and here it is!

    Basically, I wrote a button control that displays in one of 5 ways:

    • A regular button:

    image

    • A text hyperlink:

    image

    • An image:

    image

    • A button with HTML content (see this):

    image

    • A hyperlink with HTML content:

    image

    In ASP.NET terms, I have a server-side control with a ButtonType property. The markup that produces each effect is as follows:

       1: <web:ExtendedButton runat="server" ButtonType="Button" ID="button" Text="Button"/>
       2:  
       3: <web:ExtendedButton runat="server" ButtonType="Link" ID="link" Text="Link"/>
       4:  
       5: <web:ExtendedButton runat="server" ButtonType="Image" ID="image" ImageUrl="~/Images/button.png"/>
       6:  
       7: <web:ExtendedButton runat="server" ButtonType="Button" ID="buttonWithTemplate">
       8:     <Template>
       9:             <asp:Image runat="server" ImageUrl="~/Images/button.png" />
      10:             Button With Template
      11:         </Template>
      12: </web:ExtendedButton>
      13:  
      14: <web:ExtendedButton runat="server" ButtonType="Link" ID="linkWithTemplate">
      15:         <Template>
      16:             <asp:Image runat="server" ImageUrl="~/Images/button.png" />
      17:             Link With Template
      18:         </Template>
      19: </web:ExtendedButton>

    For the Image value of ButtonType, the only useful properties are ImageUrl, ImageAlign and AlternateText. These will work in the exact same way as the ImageButton control.

    For Link and Button, if the Template property is not specified, Text will be used for the textual description of the button or link. If instead a Template is available, it will be used instead of the Text. Keep in mind that you can specify almost any HTML you like for the Template, as long as it can be surrounded by an A (in the case of the Link type) or BUTTON (for Button) tags. If no Template is supplied, it will render and behave just like a LinkButton or a Button.

    This control implements IButtonControl, so it shares the usual behavior of regular button controls, like having a text property, a validation group, a postback URL, Click and Command events, event bubbling, etc. It uses the control state to save some properties, so it is safe to turn off view state in it.

    I almost forgot: here is the code!

       1: [ParseChildren(true)]
       2: [DefaultEvent("Click")]
       3: [PersistChildren(false)]
       4: [DefaultProperty("Text")]
       5: [SupportsEventValidation]
       6: [ToolboxData("<{0}:ExtendedButton runat=\"server\" Text=\"\" />")]
       7: public class ExtendedButton : WebControl, IButtonControl, IPostBackEventHandler, INamingContainer, ITextControl, IPostBackDataHandler
       8: {
       9:     #region Private static readonly fields
      10:     private static readonly Object EventClick = new Object();
      11:     private static readonly Object EventCommand = new Object();
      12:     #endregion
      13:  
      14:     #region Public constructor
      15:     public ExtendedButton() : base(HtmlTextWriterTag.Input)
      16:     {
      17:         this.ButtonType = ButtonType.Button;
      18:         this.CommandArgument = String.Empty;
      19:         this.CommandName = String.Empty;
      20:         this.OnClientClick = String.Empty;
      21:         this.ImageAlign = ImageAlign.NotSet;
      22:         this.ImageUrl = String.Empty;
      23:         this.PostBackUrl = String.Empty;
      24:         this.CausesValidation = true;
      25:         this.ValidationGroup = String.Empty;
      26:         this.UseSubmitBehavior = true;
      27:         this.Text = String.Empty;
      28:     }
      29:     #endregion
      30:  
      31:     #region Protected override methods
      32:     protected override void AddAttributesToRender(HtmlTextWriter writer)
      33:     {
      34:         base.AddAttributesToRender(writer);
      35:  
      36:         this.Page.VerifyRenderingInServerForm(this);
      37:  
      38:         if (this.ButtonType == ButtonType.Button)
      39:         {
      40:             if (this.Template == null)
      41:             {
      42:                 if (this.UseSubmitBehavior == true)
      43:                 {
      44:                     writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
      45:                 }
      46:                 else
      47:                 {
      48:                     writer.AddAttribute(HtmlTextWriterAttribute.Type, "button");
      49:                 }
      50:             }
      51:  
      52:             writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Text);
      53:             writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
      54:         }
      55:         else if (this.ButtonType == ButtonType.Image)
      56:         {
      57:             writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
      58:             writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Text);
      59:             writer.AddAttribute(HtmlTextWriterAttribute.Alt, this.AlternateText);
      60:             writer.AddAttribute(HtmlTextWriterAttribute.Type, "image");
      61:             writer.AddAttribute(HtmlTextWriterAttribute.Src, HttpUtility.HtmlEncode(this.ResolveClientUrl(this.ImageUrl)));
      62:  
      63:             if (this.ImageAlign != ImageAlign.NotSet)
      64:             {
      65:                 writer.AddAttribute(HtmlTextWriterAttribute.Align, this.ImageAlign.ToString().ToLower());
      66:             }
      67:         }
      68:  
      69:         String firstScript = this.OnClientClick;
      70:         PostBackOptions postBackOptions = this.GetPostBackOptions();
      71:                     
      72:         if (this.IsEnabled == true)
      73:         {
      74:             if (this.HasAttributes == true)
      75:             {
      76:                 String script = this.Attributes[HtmlTextWriterAttribute.Onclick.ToString()];
      77:  
      78:                 if (String.IsNullOrWhitespace(script) == false)
      79:                 {
      80:                     firstScript = String.Join(";", new String[] { firstScript, script });
      81:                     this.Attributes.Remove(HtmlTextWriterAttribute.Onclick.ToString());
      82:                 }
      83:             }
      84:  
      85:             String postBackEventReference = this.Page.ClientScript.GetPostBackEventReference(postBackOptions, true);
      86:  
      87:             if (String.IsNullOrWhiteSpace(postBackEventReference) == false)
      88:             {
      89:                 firstScript = firstScript + postBackEventReference;
      90:  
      91:                 if ((this.ButtonType == ButtonType.Link) || ((this.ButtonType == ButtonType.Button) && (this.Template != null)))
      92:                 {
      93:                     writer.AddAttribute(HtmlTextWriterAttribute.Href, postBackEventReference);
      94:                 }
      95:             }
      96:             else
      97:             {
      98:                 if (this.ButtonType == ButtonType.Link)
      99:                 {
     100:                     writer.AddAttribute(HtmlTextWriterAttribute.Href, "javascript:void(0)");
     101:                 }
     102:             }
     103:         }
     104:  
     105:         if (firstScript.Length > 0)
     106:         {
     107:             if (this.ButtonType == ButtonType.Button)
     108:             {
     109:                 if (this.UseSubmitBehavior == false)
     110:                 {
     111:                     writer.AddAttribute(HtmlTextWriterAttribute.Onclick, firstScript);
     112:                 }
     113:             }
     114:             else
     115:             {
     116:                 if (String.IsNullOrWhiteSpace(this.OnClientClick) == false)
     117:                 {
     118:                     writer.AddAttribute(HtmlTextWriterAttribute.Onclick, this.OnClientClick);
     119:                 }
     120:             }
     121:         }
     122:  
     123:         if ((this.Enabled == true) && (this.IsEnabled == false))
     124:         {
     125:             writer.AddAttribute(HtmlTextWriterAttribute.Disabled, HtmlTextWriterAttribute.Disabled.ToString().ToLower());
     126:         }
     127:     }
     128:  
     129:     protected override void OnInit(EventArgs e)
     130:     {
     131:         this.Page.RegisterRequiresControlState(this);
     132:  
     133:         if (this.ButtonType == ButtonType.Image)
     134:         {
     135:             this.Page.RegisterRequiresPostBack(this);
     136:         }
     137:  
     138:         base.OnInit(e);
     139:     }
     140:  
     141:     protected override void RenderContents(HtmlTextWriter writer)
     142:     {
     143:         if ((this.ButtonType == ButtonType.Link) || (this.ButtonType == ButtonType.Button))
     144:         {
     145:             if (this.Template != null)
     146:             {
     147:                 PlaceHolder placeHolder = new PlaceHolder();
     148:                 this.Template.InstantiateIn(placeHolder);
     149:                 this.Controls.Add(placeHolder);
     150:                 base.RenderContents(writer);
     151:             }
     152:             else
     153:             {
     154:                 if (this.ButtonType == ButtonType.Link)
     155:                 {
     156:                     writer.WriteEncodedText(this.Text);
     157:                 }
     158:             }
     159:         }
     160:     }
     161:  
     162:     protected override void LoadControlState(Object savedState)
     163:     {
     164:         Object [] state = savedState as Object [];
     165:  
     166:         this.OnClientClick = (String) state [ 1 ];
     167:         this.CausesValidation = (Boolean) state [ 2 ];
     168:         this.ValidationGroup = (String) state [ 3 ];
     169:         this.ButtonType = (ButtonType) state [ 4 ];
     170:         this.PostBackUrl = (String) state [ 5 ];
     171:         this.UseSubmitBehavior = (Boolean) state [ 6 ];
     172:         this.CommandArgument = (String) state [ 7 ];
     173:         this.CommandName = (String) state [ 8 ];
     174:         this.Text = (String) state [ 9 ];
     175:         this.ImageUrl = (String) state [ 10 ];
     176:         this.ImageAlign = (ImageAlign) state [ 11 ];
     177:  
     178:         base.LoadControlState(state [ 0 ]);
     179:     }
     180:  
     181:     protected override Object SaveControlState()
     182:     {
     183:         Object [] state = new Object [] { base.SaveControlState(), this.OnClientClick, this.CausesValidation, this.ValidationGroup, this.ButtonType, this.PostBackUrl, this.UseSubmitBehavior, this.CommandArgument, this.CommandName, this.Text, this.ImageUrl, this.ImageAlign };
     184:         return (state);
     185:     }
     186:     #endregion
     187:  
     188:     #region Public override methods
     189:     public override void RenderBeginTag(HtmlTextWriter writer)
     190:     {
     191:         this.AddAttributesToRender(writer);
     192:  
     193:         switch (this.ButtonType)
     194:         {
     195:             case ButtonType.Button:
     196:                 if (this.Template != null)
     197:                 {
     198:                     writer.RenderBeginTag(HtmlTextWriterTag.Button);
     199:                 }
     200:                 else
     201:                 {
     202:                     writer.RenderBeginTag(HtmlTextWriterTag.Input);
     203:                 }
     204:                 break;
     205:  
     206:             case ButtonType.Image:
     207:                 writer.RenderBeginTag(HtmlTextWriterTag.Input);
     208:                 break;
     209:  
     210:             case ButtonType.Link:
     211:                 writer.RenderBeginTag(HtmlTextWriterTag.A);
     212:                 break;
     213:         }
     214:     }
     215:     #endregion
     216:  
     217:     #region Protected virtual methods
     218:     protected virtual PostBackOptions GetPostBackOptions()
     219:     {
     220:         PostBackOptions options = new PostBackOptions(this, String.Empty);
     221:         options.ClientSubmit = false;
     222:  
     223:         if ((this.CausesValidation == true) && (this.Page.GetValidators(this.ValidationGroup).Count > 0))
     224:         {
     225:             options.PerformValidation = true;
     226:             options.ValidationGroup = this.ValidationGroup;
     227:         }
     228:  
     229:         if (String.IsNullOrWhiteSpace(this.PostBackUrl) == false)
     230:         {
     231:             options.ActionUrl = HttpUtility.UrlPathEncode(this.ResolveClientUrl(this.PostBackUrl));
     232:         }
     233:  
     234:         if ((this.ButtonType == ButtonType.Link) || ((this.ButtonType == ButtonType.Button) && (this.Template != null)))
     235:         {
     236:             options.ClientSubmit = true;
     237:             options.RequiresJavaScriptProtocol = true;
     238:         }
     239:  
     240:         return (options);
     241:     }
     242:  
     243:     protected virtual void OnClick(EventArgs e)
     244:     {
     245:         EventHandler handler = (EventHandler) this.Events [ EventClick ];
     246:  
     247:         if (handler != null)
     248:         {
     249:             handler(this, e);
     250:         }
     251:     }
     252:  
     253:     protected virtual void OnCommand(CommandEventArgs e)
     254:     {
     255:         CommandEventHandler handler = (CommandEventHandler) this.Events [ EventCommand ];
     256:  
     257:         if (handler != null)
     258:         {
     259:             handler(this, e);
     260:         }
     261:     }
     262:     #endregion
     263:  
     264:     #region IButtonControl Members
     265:     public event EventHandler Click
     266:     {
     267:         add
     268:         {
     269:             this.Events.AddHandler(EventClick, value);
     270:         }
     271:         remove
     272:         {
     273:             this.Events.RemoveHandler(EventClick, value);
     274:         }
     275:     }
     276:  
     277:     public event CommandEventHandler Command
     278:     {
     279:         add
     280:         {
     281:             this.Events.AddHandler(EventCommand, value);
     282:         }
     283:         remove
     284:         {
     285:             this.Events.RemoveHandler(EventCommand, value);
     286:         }
     287:     }
     288:  
     289:     [DefaultValue(true)]
     290:     [Themeable(false)]
     291:     public Boolean CausesValidation
     292:     {
     293:         get;
     294:         set;
     295:     }
     296:  
     297:     [Bindable(true)]
     298:     [DefaultValue("")]
     299:     [Themeable(false)]
     300:     public String CommandArgument
     301:     {
     302:         get;
     303:         set;
     304:     }
     305:  
     306:     [Themeable(false)]
     307:     [DefaultValue("")]
     308:     public String CommandName
     309:     {
     310:         get;
     311:         set;
     312:     }
     313:  
     314:     [DefaultValue("")]
     315:     [Themeable(false)]
     316:     [UrlProperty("*.aspx")]
     317:     public String PostBackUrl
     318:     {
     319:         get;
     320:         set;
     321:     }
     322:  
     323:     [DefaultValue("")]
     324:     [Themeable(false)]
     325:     public String ValidationGroup
     326:     {
     327:         get;
     328:         set;
     329:     }
     330:  
     331:     [DefaultValue("")]
     332:     [Localizable(true)]
     333:     [Bindable(true)]
     334:     public String Text
     335:     {
     336:         get;
     337:         set;
     338:     }
     339:     #endregion
     340:  
     341:     #region Public properties
     342:     [Browsable(false)]
     343:     [TemplateContainer(typeof(ExtendedButton))]
     344:     [TemplateInstance(TemplateInstance.Single)]
     345:     [PersistenceMode(PersistenceMode.InnerProperty)]
     346:     public ITemplate Template
     347:     {
     348:         get;
     349:         set;
     350:     }
     351:  
     352:     [DefaultValue(ButtonType.Button)]
     353:     public ButtonType ButtonType
     354:     {
     355:         get;
     356:         set;
     357:     }
     358:  
     359:     [Themeable(false)]
     360:     [DefaultValue("")]
     361:     public String OnClientClick
     362:     {
     363:         get;
     364:         set;
     365:     }
     366:  
     367:     [DefaultValue("")]
     368:     [Themeable(false)]
     369:     [UrlProperty("*.jpg;*.gif;*.png")]
     370:     public String ImageUrl
     371:     {
     372:         get;
     373:         set;
     374:     }
     375:  
     376:     [DefaultValue(ImageAlign.NotSet)]
     377:     public ImageAlign ImageAlign
     378:     {
     379:         get;
     380:         set;
     381:     }
     382:  
     383:     [DefaultValue("")]
     384:     [Themeable(false)]
     385:     public String AlternateText
     386:     {
     387:         get;
     388:         set;
     389:     }
     390:  
     391:     [DefaultValue(true)]
     392:     [Themeable(false)]
     393:     public Boolean UseSubmitBehavior
     394:     {
     395:         get;
     396:         set;
     397:     }
     398:     #endregion
     399:  
     400:     #region IPostBackEventHandler Members
     401:     void IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
     402:     {
     403:         this.Page.ClientScript.ValidateEvent(this.UniqueID, eventArgument);
     404:  
     405:         if (this.CausesValidation == true)
     406:         {
     407:             this.Page.Validate(this.ValidationGroup);
     408:         }
     409:  
     410:         this.OnClick(EventArgs.Empty);
     411:         this.OnCommand(new CommandEventArgs(this.CommandName, this.CommandArgument));
     412:  
     413:         this.RaiseBubbleEvent(this, EventArgs.Empty);
     414:     }
     415:     #endregion
     416:  
     417:     #region IPostBackDataHandler Members
     418:  
     419:     Boolean IPostBackDataHandler.LoadPostData(String postDataKey, NameValueCollection postCollection)
     420:     {
     421:         if (postDataKey == this.UniqueID)
     422:         {
     423:             if (this.ButtonType == ButtonType.Image)
     424:             {
     425:                 if ((String.IsNullOrWhiteSpace(postCollection[postDataKey + ".x"]) == false) && (String.IsNullOrWhiteSpace(postCollection[postDataKey + ".y"]) == false))
     426:                 {
     427:                     (this as IPostBackEventHandler).RaisePostBackEvent(String.Empty);                    
     428:                 }
     429:             }
     430:             else
     431:             {
     432:                 (this as IPostBackEventHandler).RaisePostBackEvent(String.Empty);
     433:             }
     434:         }
     435:  
     436:         return(false);
     437:     }
     438:  
     439:     void IPostBackDataHandler.RaisePostDataChangedEvent()
     440:     {
     441:     }
     442:  
     443:     #endregion
     444: }

    As usual, I hope you find it useful!

    Read more...

  • ASP.NET Web Forms Extensibility: Handlers

    In the .NET world, all HTTP requests, whether they be for web services (XML, WCF, Web API), pages (Web Forms and MVC), etc, are processed by a handler. Basically, a handler is a particular implementation of the IHttpHandler interface, and requests are routed to a particular handler class by one of four ways:

    • An entry on the Web.config file, on the httpHandlers section;
    • An instance returned from a Handler Factory;
    • A route handler, like in MVC or Dynamic Data;
    • Explicitly requested by the URL, in the case of ASHX generic handlers.

    The httpHandlers section can specify both a handler or a handler factory for a specific URL pattern (say, for example, /images/*.png), which may be slightly confusing. I have already discussed handler factories in another post, have a look at it if you haven’t already. A simple registration would be:

       1: <httpHandlers>
       2:     <add verb="*" path="Image.axd" type="MyNamespace.MyHandler, MyAssembly"/>
       3: </httpHandlers>

    Another option is through a route. The IRouteHandler interface defines a method GetHttpHandler which returns the route handler that will handle the request. You can register a IRouteHandler instance for a specific route by setting the RouteHandler property inside the Route class.

    Finally, there’s another kind of handler that doesn’t need registering and that is called explicitly: generic handlers. These are .ASHX markup files without any user interface elements that merely reference a code-behind class, which must implement IHttpHandler (you can also place code in the .ASHX file, inside a <script runat=”server”> declaration). Here’s an example:

       1: <%@ WebHandler Language="C#" Class="Handler" %>
       2: <script runat="server" language="C#">
       1:  
       2: public class Handler : System.Web.IHttpHandler
       3: {
       4:     //...
       5: }
       6:  
    </script>

    Having said that, what is a handler good for? The IHttpHandler interface only defines one method, ProcessRequest, and a property, IsReusable. As you can tell, this is considerably more simple than, for example, the Page class, with its myriad of virtual methods and events, which, of course, is also an implementation of IHttpHandler. Because of that, it is much more useful for handling requests that do not need a complex lifecycle. Some scenarios:

    • Downloading a file;
    • Uploading a file;
    • Streaming;
    • Redirecting;
    • Returning values for consumption by JavaScript, in AJAX style;
    • Tracing and monitoring, like ELMAH or the Trace handler;
    • Generating content dynamically, such as images.

    The IsReusable indicates to the ASP.NET infrastructure if the hander’s instance can be reused for different identical requests or if a new instance needs to be created. If you don’t store state on the handler’s class, it is safe to return true.

    As for the ProcessRequest method, a simple implementation might be:

       1: public class ImageHandler : IHttpHandler
       2: {
       3:     public void ProcessRequest(HttpContext context)
       4:     {
       5:         Bitmap bmp = new Bitmap(400, 300);
       6:  
       7:         Graphics g = Graphics.FromImage(bmp);
       8:         g.DrawRectangle(new Pen(new SolidBrush(Color.Green)), 10, 10, 300, 200);
       9:         g.DrawString(context.Request.Url.Query, new Font("Arial", 30), new SolidBrush(Color.Yellow), new PointF(10f, 10f));
      10:  
      11:         context.Response.ContentType = "image/gif";
      12:  
      13:         bmp.Save(context.Response.OutputStream, ImageFormat.Gif);
      14:     }
      15:  
      16:     public Boolean IsReusable
      17:     {
      18:         get
      19:         {
      20:             return (true);
      21:         }
      22:     }
      23: }

    This will create an image with a text string that is obtained from the query string, that is, anything in the URL after the ? symbol.

    Don’t forget to always return the appropriate content type, because the browser won’t know how to handle the content you send without it.

    One final note: from an handler you normally don't have access to the session - the Session property is null. If you need to use it, you must declare that your handler implements IRequiresSessionState or IReadOnlySessionState, the later for read-only access. That's basically what ASP.NET does when, on your page's markup, you place a EnableSessionState attribute.

    Read more...

  • NHibernate Pitfalls: Take and Where Order in LINQ Queries

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    Starting with NHibernate 3.3.3, the order by which the Take and Where operators are placed on a LINQ query matters, whereas before this version, it didn’t. This is consistent to what we would expect from a SQL query.

    For example, the two SQL queries produce different results:

       1: SELECT *
       2: FROM
       3: (
       4:     SELECT product.name, product.price, product.product_id, ROW_NUMBER() OVER (ORDER BY product.product_id) rownum
       5:     FROM product
       6:     WHERE product.price > 10
       7: ) q
       8: WHERE rownum <= 2
       9:  
      10: SELECT *
      11: FROM
      12: (
      13:     SELECT product.name, product.price, product.product_id, ROW_NUMBER() OVER (ORDER BY product.product_id) rownum
      14:     FROM product    
      15: ) q
      16: WHERE rownum <= 2
      17: AND q.price > 10

    And so do the two LINQ queries:

       1: var p1 = session.Query<Product>().Take(2).Where(x => x.Price > 10).ToList();
       2: var p2 = session.Query<Product>().Where(x => x.Price > 10).Take(2).ToList();

    See the release notes.

    Of course, besides this, both LINQ and SQL queries will only provide consistent results when applying paging if a order is given, but you probably already know that.

    Read more...

  • Custom LINQ Extensions for NHibernate

    With extensibility virtually everywhere, NHibernate is nice to work with! Consider, for example, a need to call a database-specific function in a LINQ query – a typical request.

    In SQL Server there is the SOUNDEX function, which can be used to generate a hash for a string that is based on the sound that it makes when spoken. It is a simple algorithm that was once applied manually by clerks, and can read more about it on Wikipedia. With T-SQL, it is used like this:

       1: SELECT SOUNDEX('ricardo')    --R263
       2: SELECT SOUNDEX('riicardo')   --R263
       3: SELECT SOUNDEX('rycardo')    --R263

    In order to use this function from LINQ, we need to have a .NET method with an appropriate signature:

       1: public static class StringExtensions
       2: {
       3:     [LinqExtensionMethod]
       4:     public static String Soundex(this String input)
       5:     {
       6:         throw new NotImplementedException();
       7:     }
       8: }

    Did you notice the [LinqExtensionMethod] attribute? Well, that’s all it takes! Smile We can have code like this:

       1: String nameHash = session.Query<Customer>().Select(x => x.Name.Soundex()).First();

    And NHibernate will translate this to the appropriate function call!

    Of course, this will make the LINQ expression run in the database, if you want it to run as well on the client side, here’s a possible implementation of the SOUNDEX algorithm:

       1: public static class StringExtensions
       2: {
       3:     private const String values = "01230120022455012623010202";
       4:     private const Int32 encodingLength = 4;
       5:  
       6:     [LinqExtensionMethod]
       7:     public static String Soundex(this String input)
       8:     {
       9:         Char prevChar = ' ';
      10:  
      11:         input = Normalize(input);
      12:         
      13:         if (input.Length == 0)
      14:         {
      15:             return (input);
      16:         }
      17:  
      18:         StringBuilder builder = new StringBuilder();
      19:         builder.Append(input[0]);
      20:  
      21:         for (Int32 i = 1; ((i < input.Length) && (builder.Length < encodingLength)); ++i)
      22:         {
      23:             Char c = values[input[i] - 'A'];
      24:  
      25:             if ((c != '0') && (c != prevChar))
      26:             {
      27:                 builder.Append(c);
      28:                 prevChar = c;
      29:             }
      30:         }
      31:  
      32:         while (builder.Length < encodingLength)
      33:         {
      34:             builder.Append('0');
      35:         }
      36:  
      37:         return (builder.ToString());
      38:     }
      39:  
      40:  
      41:     private static String Normalize(String text)
      42:     {
      43:         StringBuilder builder = new StringBuilder();
      44:  
      45:         foreach (Char c in text)
      46:         {
      47:             if (Char.IsLetter(c) == true)
      48:             {
      49:                 builder.Append(Char.ToUpper(c));
      50:             }
      51:         }
      52:  
      53:         return (builder.ToString());
      54:     }
      55: }

    As always, hope this helps! Winking smile

    Read more...