Tuesday, October 25, 2011

RequireHttps attribute and IIS Express

Perhaps you, like me, have been frustrated by the RequireHttpsAttribute functionality in MVC.  It's a great concept; an easy attribute class to force redirection to a secure channel, but it was kinda frustrating how it was implemented, especially since the advent of IIS Express.

If you didn't know, IIS Express is a great tool that integrates seamlessly into Visual Studio 2010.  It works very well, and you can enable HTTP over SSL with the click of a mouse.  I love it; there's only one problem: it assigns both the cleartext and the secure channel to unique TCP ports.  From IIS Express's perspective, this is a good thing, keeping everything nice and separate... from a development perspective, this is annoying, because we do not have the ability to tell our code which port to use when redirecting to the secure channel.

Well this cheesed me off enough that I decided to do something about it.  I liked the idea of an attribute class controlling the redirect; it kept my controllers clean from clutter; however, the IIS secure port is machine specific, and in production it's almost always going to be 443.  Attributes do not support variable arguments, so I had to get a little creative.  What I ended up with is this:


using System.Configuration;

namespace System.Web.Mvc
{
[AttributeUsage(AttributeTargets.Class)]
public class RedirectHttpsAttribute : ActionFilterAttribute
{
#region Properties
private static string _DisableHttpsRedirect;
/// <summary>
/// When true, forcing a redirect to a secure page is suppressed.
/// </summary>
/// <remarks>
/// This value can be set in the config file under the "DisableHttpsRedirect" app setting.
/// </remarks>
public static bool DisableHttpsRedirect
{
get
{
if (string.IsNullOrEmpty(_DisableHttpsRedirect))
{
_DisableHttpsRedirect = (ConfigurationManager.AppSettings["DisableHttpsRedirect"] ?? "False");
}

bool retValue;
if (!bool.TryParse(_DisableHttpsRedirect, out retValue))
{
retValue = false;
}

return retValue;
}

set
{
_DisableHttpsRedirect = value.ToString();
}

}

private static string _SecurePort;
/// <summary>
/// When set to a number, explicitly declares the port of the URL in the redirect string.
/// When set to -1, uses the default protocol port (no port number in the string)
/// </summary>
/// <remarks>
/// This value can be set in the config file under the "SecurePort" app setting.
/// </remarks>
public static int SecurePort
{
get
{
if (string.IsNullOrEmpty(_SecurePort))
{
_SecurePort = (ConfigurationManager.AppSettings["SecurePort"] ?? "-1");
}

int retValue;
if (!int.TryParse(_SecurePort, out retValue))
{
retValue = -1;
}

return retValue;
}

set
{
_SecurePort = value.ToString();
}
}
#endregion

public override void OnResultExecuting(ResultExecutingContext filterContext)
{

//Allow the redirect to be disabled in the config file.  This may be necessary for testing purposes.
if (!filterContext.HttpContext.Request.IsSecureConnection &&
!DisableHttpsRedirect)
{
//replace the contents of the nonsecure string with the proper protocol and port number.
UriBuilder ub = new UriBuilder(filterContext.HttpContext.Request.Url);
ub.Scheme = "https";
ub.Port = SecurePort;

//direct the context to redirect to the proper secure channel.
filterContext.Result = new RedirectResult(ub.ToString());
filterContext.Result.ExecuteResult(filterContext);
}

return;
}
}
}

This allows the HTTPS port to be configured in the web.config file as follows:

  • Setting: "DisableHttpsRedirect" this can be used on a dev machine with no access to SSL; shouldn't be necessary in most cases with IIS express, but it's possible.  The default value is "false".  Whenever you're forcing control of an application somewhere else, it's a good idea to expose a means to override the behavior for isolation purposes.
  • Setting: "SecurePort" this allows you to set the secure port number in your web.config file.  The default is -1 which the URL builder will take to mean the default port (in the case of HTTPS, that is 443)  This way, you can have your production environment run without a port number specifier, which would look goofy.

There!  All we have to do now is make an abstract Controller class tagged with the [RedirectHttps] attribute, have the rest of our controllers inherit from it and configure the joker in the web config.  Problem solved.

Wednesday, October 12, 2011

MVC3 Helper methods supporting Linq Expressions

I was a bit frustrated with the .DropDownFor() extension on the HtmlHelper class.  There was no access to the OPTION tags, and I've never been a fan of the SelectList object.  I wanted to put some tool tip text (using the title attribute) on the options to provide more context in the selection.  Of course there was no way to do that with the .DropDownFor() helper method.  So, time to roll my own.

Only thing was, I'd never written an extension that used a Linq expression before, so it took a little research.  Finally I found this post (I heart StackOverflow) and piecing it together from there, came up with this joker:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;


namespace System.Web.Mvc
{
public static class MoreHelpers
{
public static HtmlString SelectFor<TModel, TProperty, TListItem>(
this HtmlHelper<TModel> htmlHelper, 
Expression<Func<TModel, TProperty>> expression,
IEnumerable<TListItem> enumeratedItems,
string idPropertyName,
string displayPropertyName,
string titlePropertyName,
object htmlAttributes
)
 where TModel : class
{
//initialize values
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var propertyName = metaData.PropertyName;
var propertyValue = metaData.Model.ToStringOrEmpty();
var enumeratedType = typeof(TListItem);

//build the select tag
var returnText = string.Format("<select id=\"{0}\" name=\"{0}\"", HttpUtility.HtmlEncode(propertyName));
if (htmlAttributes != null)
{
foreach (var kvp in htmlAttributes.GetType().GetProperties()
.ToDictionary(p => p.Name, p => p.GetValue(htmlAttributes, null)))
{
returnText += string.Format(" {0}=\"{1}\"", HttpUtility.HtmlEncode(kvp.Key),
HttpUtility.HtmlEncode(kvp.Value.ToStringOrEmpty()));
}
}
returnText += ">\n";


//build the options tags
foreach (TListItem listItem in enumeratedItems)
{
var idValue = enumeratedType.GetProperties()
.FirstOrDefault(p => p.Name == idPropertyName)
.GetValue(listItem, null).ToStringOrEmpty();
var titleValue = enumeratedType.GetProperties()
.FirstOrDefault(p => p.Name == titlePropertyName)
.GetValue(listItem, null).ToStringOrEmpty();
var displayValue = enumeratedType.GetProperties()
.FirstOrDefault(p => p.Name == displayPropertyName)
.GetValue(listItem, null).ToStringOrEmpty();
returnText += string.Format("<option value=\"{0}\" title=\"{1}\"",
HttpUtility.HtmlEncode(idValue), HttpUtility.HtmlEncode(titleValue));
if (idValue == propertyValue)
{
returnText += " selected=\"selected\"";
}
returnText += string.Format(">{0}</option>\n", displayValue);
}


//close the select tag
returnText += "</select>";
return new HtmlString(returnText);
}


public static string ToStringOrEmpty(this object target)
{
if (target == null) return string.Empty;
return target.ToString();
}
}
}


Works like a champ!

Tuesday, October 11, 2011

Extension Methods to Translate Interface Values

Today I'm going to talk about using two of my favorite concepts in C#:  interfaces and extension methods.

There are times when I'm using the Entities Framework with MVC.  For any writable objects in my MVC project, I really do not want to shoehorn them into an Entities object; EF will bark at you, there's a lot of complications, and the self-tracking stuff will actually get in your way.

However, at some point, my MVC model needs to allow me to get the data from an Entities data model object, and translate it to view model object, and vice-versa.  For example, let's say we have a database table of Employees:

create table Employees
(
EmployeeID int identity not null primary key,
GivenName varchar(35) not null,
FamilyName varchar(35) not null,
DepartmentID int not null
);

In EF, this will be an Employee object with four primitive properties (EmployeeID, GivenName, FamilyName, and DepartmentID) plus a navigation object property pointing to the Departments table called Department (assuming of course that DepartmentID is a foreign key and you are keeping foreign keys around... I like to) of type Department, another EF entity.

If we are making a model for MVC to edit Employee records, you don't want to use the Entity object; you cannot define any validation properties, the "glue" that holds an EF object is not translatable to the a serializable forms object (well, not strictly true, but it's a lot more work), and of course data state cannot be maintained very easily in a web session... you usually don't want it to anyway.

So we need to define a model object.  Let's do so now:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;


namespace MyMVCProject.Models.Employees
{
public class EditModel
{
public int EmployeeID { get; set; }


[Required]
[MaxLength(35)]
[Display(Name="Given Name")]
public string GivenName { get; set; }


[Required]
[MaxLength(35)]
[Display(Name="Family Name")]
public string FamilyName { get; set; }


[Required]
public int DepartmentID { get; set; }


public IEnumerable<Department> AvailableDepartments { get; set; }
}
}

There's a lot of overlap between the view model and the entity object; after all, they are referencing the same thing, but because they are meant to do different things they have to be separate.

But now, in the controller, every time we want to link the two objects, we need to go through a translation mechanism:

using System.Web.Mvc;
using MyMVCProject.Models.Employees;
using MyMVCProject.DataModel.Entities;
namespace MyMVCProject.Controllers
{
public class EmployeesController : Controller
{
protected EntitiesUnitOfWork UnitOfWork = new EntitiesUnitOfWork();
public ActionResult Edit(int id)
{
var entity = UnitOfWork.GetEmployee(id);
var model = new EditModel();
model.EmployeeID = entity.EmployeeID;
model.GivenName = entity.GivenName;
model.FamilyName = entity.FamilyName;
model.DepartmentID = entity.DepartmentID;
model.AvailableDepartments = UnitOfWork.GetAvailableDepartments();
return View(model);
}

[HttpPost]
public ActionResult Edit(EditModel model)
{
if (ModelState.IsValid)
{
var entity = UnitOfWork.GetEmployee(model.EmployeeID);
entity.GivenName = model.GivenName;
entity.FamilyName = model.FamilyName;
entity.DepartmentID = model.DepartmentID;
UnitOfWork.Save();
return RedirectToAction("Index");
}
else
{
model.AvailableDepartments = UnitOfWork.GetAvailableDepartments();
return View(model);
}
}
}
}

...and that's just for one view model.  There's likely to be a CreateModel, and maybe a DetailModel as well that the translation would have to be coded for.  That's a lot of repeated code.

So how do you get around having to do that all the time?  With interfaces!

In our data model namespace, we can define an IEmployee interface like so:

namespace MyMVCProject.DataModel.Entities
{
public interface IEmployee
{
int EmployeeID { get; set; }
int DepartmentID { get; set; }
string GivenName { get; set; }
string FamilyName { get; set; }
}
}

...then, make a public partial class Employee in the data model namespace that implements the interface:

namespace MyMVCProject.DataModel.Entities
{
public partial class Employee : IEmployee
{
//nothing needed here; the T4 generated code has already implemented the interface; 
//we are simply defining the class as IEmployee.
}
}

Now, what I like to do at this point (and this is simply a personal preference) is, in the same file where the interface is defined, create a partial static class with an extension method for the translation.  Note that the key properties will need to be handled with care; you don't want to change a key property unless it has not been set.  EF will bark at you, and rightfully so.

namespace MyMVCProject.DataModel.Entities
{
public interface IEmployee
{
int EmployeeID { get; set; }
int DepartmentID { get; set; }
string GivenName { get; set; }
string FamilyName { get; set; }
}

public static partial class Translation
{
public static T Translate<T>(this T current, IEmployee source) where T : IEmployee
{
if (current.EmployeeID == 0)
{
current.EmployeeID = source.EmployeeID;
}
current.DepartmentID = source.DepartmentID;
current.FamilyName = source.FamilyName;
current.GivenName = source.GivenName;
return current;
}
}
}

After this, go back to the MVC view model, and add the reference to the IEmployee interface and the data model namespace.  No other work should be necessary if you kept the property names and data types the same.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using MyMVCProject.DataModel.Entities;
namespace MyMVCProject.Models.Employees
{
public class EditModel : IEmployee
{
public int EmployeeID { get; set; }

[Required]
[MaxLength(35)]
[Display(Name="Given Name")]
public string GivenName { get; set; }

[Required]
[MaxLength(35)]
[Display(Name="Family Name")]
public string FamilyName { get; set; }

[Required]
public int DepartmentID { get; set; }

public IEnumerable<Department> AvailableDepartments { get; set; }
}
}

Now we can use the method extensions in our controller with impunity:

using System.Web.Mvc;
using MyMVCProject.Models.Employees;
using MyMVCProject.DataModel.Entities;
namespace MyMVCProject.Controllers
{
public class EmployeesController : Controller
{
protected EntitiesUnitOfWork UnitOfWork = new EntitiesUnitOfWork();
public ActionResult Edit(int id)
{
var entity = UnitOfWork.GetEmployee(id);
var model = new EditModel()
.Translate(entity);
model.AvailableDepartments = UnitOfWork.GetAvailableDepartments();
return View(model);
}

[HttpPost]
public ActionResult Edit(EditModel model)
{
if (ModelState.IsValid)
{
var entity = UnitOfWork.GetEmployee(model.EmployeeID)
.Translate(model);
UnitOfWork.Save();
return RedirectToAction("Index");
}
else
{
model.AvailableDepartments = UnitOfWork.GetAvailableDepartments();
return View(model);
}
}
}
}

While this does not seem to save a lot of code in this example, keep in mind, this is a very simple example; few models actually contain so few properties, and we have changed the translation between the view model object(s) and the data model object to exactly one place for everything.  When you add additional models (like a CreateModel, where you need different validation logic), instead of doubling your text, it's just one line that will predictably behave exactly as all the other calls to this extension method.


















Wednesday, October 5, 2011

Unit Testing - A Pragmatic Approach

There's a lot of "should dos" out there regarding unit tests- Test Driven Development (TDD) is a concept a lot of professional developers get behind with an almost religious fervor, pointing to simple examples of how to implement a test-driven method which usually involves:
  • Write a test
  • Make the test fail
  • Write the code
  • Make the test pass
  • Profit.
...but really, this is completely impractical for a number of reasons:

1) Most compiled languages will require you to write the code first, otherwise the test will have nothing to actually test.  Writing a test for Foo() is great, except if Foo() doesn't exist, this will fail for the wrong reasons.  So building the test first doesn't always make a lot of sense.

2) Even simple methods have several tests that are applicable for each.  Consider the following code:

public bool Foo(string bar, int wee)
   {
   if (bar == "foo" && ((1 / wee) * 10) > 1))
      {
      return true;
      }
   else
      {
      return false;
      }
   }


How many conditions do we need to check for here, to see if the method:
  • Produces the proper output
  • Handles odd inputs gracefully
Let us count the ways:
  1. Test string bar for empty string condition
  2. Test string bar for null value condition
  3. Test string bar for "foo" condition
  4. Test string bar for "Foo" condition
  5. Test string bar for "Something Else" condition
  6. Test int wee for zero condition
  7. Test int wee for negative condition
  8. Test int wee for 5 condition
  9. Test int wee for "not 5" condition
Why so many tests?  For a nullable input, not testing a null value is asking for trouble.  Likewise, strings can easily be empty, and often when not expected.  These are the sorts of things that unit tests are meant to help with: testing for possible but unexpected data.

For integers, testing for zero is a given.  In the method above, a value of zero will throw a DivideByZero exception.  What if we were multiplying that number against a cost value, and someone inadvertently tossed an Int32.MaxValue as an argument?  Not testing for the default value of any variable is asking for trouble.  Likewise, negative numbers... maybe the code you are using this method with has a buggy math operation, if the application bombs in Foo() because it doesn't recognize the problems inherent in other code, you have failed at testing.  Edge cases are usually a good idea too. (max and min values)

I have 9 tests listed for method Foo.  And that's normal!  This is a fairly well-tested method.  You could take some shortcuts, but ultimately, you are looking at 3-4 tests per argument at a minimum, not to mention dealing with potential combinations that need to be handled gracefully.
    3) If you are in a technology-centric company, you likely have leadership that understands the importance of unit testing and quality control.  If, however, you are employed in the other 95% of businesses, your chances of having leadership that understands and appreciates this sort of effort dramatically decreases.  Technology people want accurate results; business people tend to want quick results, and the two rarely overlap.

    These are the reasons I have never been a big fan of TDD... but that doesn't mean I'm not a fan of unit testing.  Unit testing is an incredibly important part of any quality software production.  However, following doctrine for how unit testing should be done has resulted in slowdowns that bosses usually do not appreciate.

    Here are some ways I have made unit testing work for me and have given me a degree of confidence in the code I have produced:


    • Always test for default values of your argument types.  When coding, it's easy to declare/ instantiate an object, expect it to be properly populated, and then pass it into a method... only to find out that the object was not, in fact, properly populated.  Nullable objects should be checked for null values, integers should be checked for zero, etc.  Check for the values in your method, and throw the proper exception (ArgumentNullException or OutOfRangeException) when the data needs to actually be used.  Provide enough info to understand where the error occurred.



    • Keep your exceptions granular, so you can test for a specific condition, for example:


    bool Foo(string foo)
    {
       if (foo == null) throw new ArgumentNullException("foo");
       if (foo == string.Empty) throw new ArgumentException("parameter 'foo' cannot be empty")
    ...
    }


              In this example, we have two easily testable scenarios:

    [Test, ExpectedException(typeof(ArgumentException))]
    public void testFooEmptyStringArg()
    {
       var f = Foo(string.Empty);
    }

    [Test, ExpectedException(typeof(ArgumentNullException))]
    public void testFooEmptyStringArg()
    {
       var f = Foo(null);
    }



    • Test against interfaces as much as possible.  Internal workings of components should be tested, but the public usage of the classes and methods are the ones that will need the most scrutiny.
    • Manage your time.  Remember, in a perfect world, you'd have infinite time to create the perfect code and unit tests... but development is generally funded by business, and in business, time is money.  Start with the most obvious conditions to test, get a degree of confidence, and expect to come back to troubleshoot and fix bugs.  Whenever you fix a bug, add a unit test to make sure that bug never "reappears."
    • Always keep in mind the intent behind unit testing is not to create bug-free code, nor is it to provide a troubleshooting mechanism for bugs.  It is a validation tool to confirm that your code behaves the way you meant it to... and when you have to change your code base, well-written unit tests will show you what your latest changes have broken in other places, which will drastically reduce regression testing and user acceptance time.
    That's a basic overview.  Comments are welcome (I expect a few will be how wrong I am)...

    Tuesday, October 4, 2011

    Entity Framework - A Review in Practice

    I started playing with EF with .NET 4.0.  I came into it with a reserved attitude - my coworkers shoehorned it into a new project we were working on; I was more comfortable with ADO.NET, and was skeptical that it would make our lives easier as it was supposed to, but as a professional geek I have a responsibility to give new tech a fair shake.  Now I have used and am currently using EF for a number of projects that I am working on, and I feel comfortable giving my two cents about the product.

    Coming from a strong DB background, I prefer to model in the database environment.  Conveniently, the EF model generator supports this.  You build your schema, define your keys, create your relationships and stored procedures, and then, once your data model is complete, use EF to generate your object model for use in code.  Invoke a couple T4 templates, and you're off, cooking with gas.

    The support for this is pretty good as long as you are not doing anything esoteric in your data model; of course, in almost any business application, there is usually a few things that are... off.  Business object models rarely have the consistency that data object models do.  The instant you step off the beaten path with EF, you are in a world of headaches.  The one-offs are dangerous, because all that time you spend just trying to get your model to validate eats up what you would have saved if you had used a more primitive but flexible mechanism.

    Trying to get a model to validate with one small difference from what EF thinks you actually want has caused me to scream at my computer loud obscenities at all hours of the night.  Good thing I live alone.  The EF interpreter of the schema is sophisticated, but not flexible, and if you are fairly versatile in the way you build your schema, EF is likely to frustrate the hell out of you.

    All bitching aside, one of the good things about EF is if, as you go along, you realize you need to add a column to a table that is referenced in six other spots, you can, with very little difficulty.  This is a huge timesaver over editing a dozen stored procedures, and why I still use EF despite the effects it has on my blood pressure.

    Integrating your object model into a UnitOfWork pattern is fairly straightforward, although I have to admit the first few times we tried we way overthought it until we'd painted ourselves into a corner, and had to rip it all out and start over again; I think this had more to do with us not really understanding the UnitOfWork pattern, though, and less with EF.

    One problem I had with EF was the way it handles child objects in the graph.  The .Include() method adds the child objects to the target object from the repository with the relative ease you would expect from an ORM; God help you if you want to alter those child objects as they relate to the parent object, though.  It's possible to do, but completely counter-intuitive, and detracts from the benefit of the ORM model, which allows us to treat data as objects since we tend to think that sort of way.  With all of the automation involved in the underpinnings of the EF object repositories, you'd think they'd have a much more elegant way of handling this... but they don't.

    Another issue I had was with portability.  There were times I wanted to take a full object graph and transport it to another system.  The actual data was serializable; the underpinnings of the "glue" that held the object properties together (navigation properties) were not, so much.  To me, it would make perfect sense to allow the developer to define a key translation behavior (do I keep this identity-based key, or make a new record?) and insert/update an entire graph from another system.  Portability and generics are not well supported in EF.

    The biggest thing I don't like about EF is there is no concept of a "JDI button"... where JDI stands for "Just Do It".  EF will try to validate the model against the database, and against its own internal configuration, but it's very sensitive, and if it encounters a case where it imagines something could go wrong, it will not allow you to proceed, even if you know the condition it is worrying about will never occur, based on business logic or the data being transformed before it got to that point.  Everything is an error, and the errors are cryptic and vague... and not well documented.  Just make it a warning, let me deal with the problem when (if) it actually is a problem.  Please!

    An interesting "bug" I've seen with EF is the way it sometimes handles relationships... there are times when several foreign key relationships are designed in exactly the same manner, but are interpreted differently in EF.  A manual tweak will make the problem go away, but it's bizarre to see it in the first place.

    The way the EF lays out the object model is nothing short of bizarre.  Luckily, you can reorganize the model, and it will remember your change.

    All in all, I am not happy with EF in its current incarnation, but I still use it because for the most part it is better than the alternative.  Still, by version 4 I'd expect a far more mature product.