My Blog

  Home  |   Contact  |   Syndication    |   Login
  8 Posts | 0 Stories | 17 Comments | 0 Trackbacks

News

Archives

Thursday, July 15, 2010 #

A while back I wrote about using a semantic model for HTML generation. Today I finally got around to posting our (Phoenix Web Group) extensions for Fubu's HtmlTags library online. The code can be found here.

We added a bunch of missing tags and some extention methods to help make working with nesting and tables easier. (We prefer using params parameters instead an array parameters.) We also added a single static entry point into all of the tags: the Tags class.

Here is some code using our extensions that renders a typical edit field with a label:

public static HtmlTag EditFieldFor(Type modelType, object model, PropertyInfo fieldProperty)
{
	return Tags.Div
		.AddClass("fields")
		.Nest(
			ViewConventionExtensions
				.LabelFor(modelType, model, fieldProperty)
				.AddClass("label"),
			Tags.Div
				.AddClass("field")
				.Nest(
					ViewConventionExtensions
						.InputFor(modelType, model, fieldProperty)
				)
		);
}

The real power of using HtmlTags becomes apparent when you use them with HTML input conventions which will be the topic of my next post.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Friday, May 21, 2010 #

Lately I've been using JBar, a very neat jQuery plugin for displaying notifications in my web applications. Unfortunately the original version of JBar only supports binding to the click event of a DOM item. In order to get around this limitation I have modified the source code and posted an updated version on my GitHub account here. The modified version allows you to display a JBar notification by calling a method. I typically use it to display succes or failure messages when doing Ajax calls.

I have also included some additional CSS and JS so that you can diplay different styles of notifications.

showNotification(message) shows a green "success" message.

showWarning(message) shows an orange "warning" message.

showMessage(message, className) allows you to specify a custom class to apply to the notification for additional styling purposes.

A web page with samples is included.

 

Get the code here.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Monday, May 17, 2010 #

Goals

  • Create a class that associates a numeric quantity with a unit of measurement.
  • Provide support for simple arithmetic and comparison operations.

Implementation

  • An immutable class (Could have been struct but I may try inheritance later)
  • Unit is stored in an enumeration
  • Supported operations:
  • Addition w/ like units
  • Subtraction w/ like units
  • Multiplication by scalar
  • Division by scalar
  • Modulus by scalar
  • Equals()
  • >, >=, <, <=, ==
  • IComparable
  • ToString()
  • Implicit cast to Decimal

The Source

The souce can be downloaded from Github.

Notes

  • This class does not support any arithmetic that would modify the unit.
  • This class is not suitable for manipulating currencies.

Future Ideas

  • Have a CompositeQuantity class that would allow quantities with unlike units to be combined.
  • Similar currency class with support for allocations/distributions.
  • Provide conversion between units. (Actually I think this would be best placed in an external service. Many situations I deal with require some sort of dynamic conversion ratio.)
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Wednesday, April 21, 2010 #

In this post I look into the code smell that is HTML literals and show how we can refactor these pesky strings into a friendlier and more maintainable model.

 

The Problem

When I started writing MVC applications, I quickly realized that I built a lot of my HTML inside HtmlHelpers. As I did this, I ended up moving quite a bit of HTML into string literals inside my helper classes. As I wanted to add more attributes (such as classes) to my tags, I needed to keep adding overloads to my helpers. A good example of this end result is the default html helpers that come with the MVC framework. Too many overloads make me crazy!

The problem with all these overloads is that they quickly muck up the API and nobody can remember exactly what order the parameters go in. I've seen many presenters (including members of the ASP.NET MVC team!) stumble before realizing that their view wasn't compiling because they needed one more null parameter in the call to Html.ActionLink().

What if instead of writing

Html.ActionLink("Edit", "Edit", null, new { @class = "navigation" })

we could do

Html.LinkToAction("Edit").Text("Edit").AddClass("navigation")

? Wouldn't that be much easier to remember and understand?  We can do this if we introduce a semantic model for building our HTML.

 

What is a Semantic Model?

According to Martin Folwer, "a semantic model is an in-memory representation, usually an object model, of the same subject that the domain specific language describes." In our case, the model would be a set of classes that know how to render HTML. By using a semantic model we can free ourselves from dealing with strings and instead output the HTML (typically via ToString()) once we've added all the elements and attributes we desire to the model.

There are two primary semantic models available in ASP.NET MVC: MVC 2.0's TagBuilder and FubuMVC's HtmlTags.

 

TagBuilder

TagBuilder is the html builder that is available in ASP.NET MVC 2.0. I'm not a huge fan but it gets the job done -- for simple jobs.  Here's an overview of how to use TagBuilder. See my Tips section below for a few comments on that example.

The disadvantage of TagBuilder is that unless you wrap it up with our own classes, you still have to write the actual tag name over and over in your code. eg. new TagBuilder("div") instead of new DivTag(). I also think it's method names are a little too long. Why not have AddClass() instead of AddCssClass() or Text() instead of SetInnerText()? What those methods are doing should be pretty obvious even in the short form.

I also don't like that it wants to generate an id attribute from your input instead of letting you set it yourself using external conventions. (See GenerateId() and IdAttributeDotReplacement)). Obviously these come from Microsoft's default approach to MVC but may not be optimal for all programmers.

 

HtmlTags

HtmlTags is in my opinion the much better option for generating html in ASP.NET MVC. It was actually written as a part of FubuMVC but is available as a stand alone library.

HtmlTags provides a much cleaner syntax for writing HTML. There are classes for most of the major tags and it's trivial to create additional ones by inheriting from HtmlTag. There are also methods on each tag for the common attributes. For instance, FormTag has an Action() method. The SelectTag class allows you to set the default option or first option independent from adding other options. With TagBuilder there isn't even an abstraction for building selects!

The project is open source and always improving. I'll hopefully find time to submit some of my own enhancements soon.

 

Tips

1) It's best not to have insanely overloaded html helpers. Use fluent builders.

2) In html helpers, return the TagBuilder/tag itself (not a string!) so that you can continue to add attributes outside the helper; see my first sample above.

3) Create a static entry point into your builders. I created a static Tags class that gives me access all the HtmlTag classes I need. This way I don't clutter my code with "new" keywords. eg. Tags.Div returns a new DivTag instance.

4) If you find yourself doing something a lot, create an extension method for it. I created a Nest() extension method that reads much more fluently than the AddChildren() method. It also accepts a params array of tags so I can very easily nest many children.

 

I hope you have found this post helpful. Join me in my war against HTML literals! I’ll have some more samples of how I use HtmlTags in future posts.

Update: more info on our HtmlTag extensions here.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Wednesday, February 24, 2010 #

Update: I have updated the repository to include references to Fubu's Dlls instead of copying their code directly.

 

Here’s something fun that I’ve been playing with. A few weeks ago I saw Jeremy Miller’s post “Shrink your view’s with FubuMVC’s Html conventions” and knew I had to have this functionality in my Microsoft MVC applications. I pulled the source and started writing an adapter to make it work. I hope the FubuMVC guys don’t mind that I’ve borrowed some of their hard work.

What are Html Conventions?

Html conventions are essentially opinionated input builders. Instead of explicitly declaring what types of inputs and outputs will be rendered at design time, the designer instead simply states that there will be an input or output rendered (or possibly not rendered, actually). In code this might look like:

 
<% Html.LabelFor(x => x.Price) %>: <% Html.InputFor(x => x.Price) %>

The input builders available in MVCContrib and MVC 2 (as far as I know) are rendered using templates. You can define a String.aspx file that contains a text box or a Datetime.aspx that contains a date picker. What this means is that the output is relatively static unless you flood your template with conditional logic*. With FubuMVC’s input builders, you have the flexibility of building an HtmlTag tree at runtime. This allows you to define modifiers that alter the output, for example tagging an input with a “required” css class if the underlying view model property has a Required attribute or adding blank options to a drop down list.

*I think you can probably match Fubu’s functionality with MVCContrib, but at the cost of readability.

Why Use Html Conventions?

I use Html conventions in my applications because they provide a single point where I can immediately alter the appearance and functionality of the site. I don’t need to modify every view if I decide to swap out one style of date picker with another.

In my applications, I use the view model to define a contract between the view and the remainder of the application (controller + action filters) describing what data will be available. On the view model itself, I provide attribute annotations where necessary to provide the view with metadata about how to render certain controls. For instance I have BigTextAttribute which renders a text area; WithBlankOption which renders a blank drop down option; and AjaxOptions which renders an empty drop down that get’s populated by AJAX.

How They Work

In your IoC container you must register a class that provides the convention configuration. This class defines tag builders and modifiers that get executed based on whether they match the property/input being rendered. The render engine finds the first tag builder that matches the input and executes that. Then it finds all the modifiers which match the input and executes them on the tag. Lastly this tag (tree) is ToStringed and added to the page markup.

Sample Conventions

Here are the conventions that I am using in a production application right now.

 
public PMHtmlConventions()
{
	Editors.IfPropertyTypeIsEnum().BuildBy(EnumDropDownBuilder.Build);
	Editors.IfPropertyIs<bool>().BuildBy(req => new CheckboxTag(req.Value<bool>()));
	Editors.IfPropertyIs<DateTime?>().BuildBy(req => new CalendarTextBox(req.ElementId, req.Value<DateTime?>()));

	Editors.IfPropertyIs<DateTime>().BuildBy(req => new CalendarTextBox(req.ElementId, req.Value<DateTime>()));
	Editors.IfPropertyHasAttribute<AjaxOptionsAttribute>().BuildBy(SelectBuilder.AjaxBuild);
	Editors.IfPropertyHasAttribute<OptionsFromAttribute>().BuildBy(SelectBuilder.Build);
	Editors.IfPropertyHasAttribute<BigTextAttribute>().BuildBy(BigTextBuilder.Build);

	// Default text box
	Editors.Always.BuildBy(TagActionExpression.BuildTextbox);

	Editors.Always.Modify(AddElementName);

	Displays.Always.BuildBy(req => new HtmlTag("span").Text(req.StringValue()));
	Labels.Always.BuildBy(req => new HtmlTag("span").Text(LabelingConvention.GetLabelText(req.Accessor)).Id("label{0}".ToFormat(req.Accessor.Name)));
}

And an example of what a drop down builder looks like.

public class SelectBuilder
{
	public static HtmlTag Build(ElementRequest req)
	{
		return new SelectTag(BuildOptions(req)).Id(req.ElementId);
	}

	private static Action<SelectTag> BuildOptions(ElementRequest req)
	{
		var fromAttribType = typeof(OptionsFromAttribute);
		var fromAttrib = req.Accessor.GetAttribute<OptionsFromAttribute>();
		if (fromAttrib == null)
		{
			throw new Exception(string.Format("Expected property '{0}' to have decorator: {1}.", req.ElementId, fromAttribType.Name));
		}
		var fromProperty = req.Accessor.DeclaringType.GetProperties().FirstOrDefault(p => p.Name == fromAttrib.PropertyName);
		if (fromProperty == null)
			{
			throw new Exception(string.Format("Could not find options source property '{0}' on type '{1}'", fromAttrib.PropertyName, req.Accessor.DeclaringType.Name));
			}
		var optionPairs = fromProperty.GetGetMethod().Invoke(req.Model, null) as IDictionary;
		var hasBlankOption = req.Accessor.HasAttribute<WithBlankOption>();
		return tag =>
		   {
			   foreach (var key in optionPairs.Keys)
			   {
				   tag.Option(optionPairs[key].ToString(), key);
			   }
			   if (req.RawValue != null)
			   {
				   tag.SelectByValue(req.RawValue.ToString());
			   }
		   };
	}
}

The source

You can download the source from here. I included the assemblies necessary to get this working. The FubuMVC source is available here. There is a sample web application. Navigate to /Product/Index to see the very simple output.

Note that if you would like to use this with Spark you will need to define your own typed base view as described here.

 

I hope all of you enjoy working with conventions as much as I have! Thanks for the feedback.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Tuesday, February 23, 2010 #

While my home development computer is fried I’m going to hack away at my backlog of non-code related posts. Today I’d like to discuss some of the advantages and disadvantages of using Microsoft MVC over WebForms.

First of all, MVC is not the end all, magical platform that many people would like you to believe. In fact I wouldn’t even recommend it to beginner developers. However, if you have experience with .NET and you’re willing to put in the time to learn how MVC works, you will find that it offers much more control than WebForms.

Stateless Development

The biggest difference between WebForms and MVC (and one that is often overlooked) is that MVC is a stateless framework. WebForms (and the associated page lifecycle and viewstate, etc) was designed to bring the familiarity of stateful development found in WinForms to the web. Unfortunately for Microsoft, the web is inherently stateless (each HTTP request is independent from any prior request) so a layer of abstraction was introduced to fudge a connection.

Because MVC does not have any abstraction over a raw HTTP request, there are no Page_Load methods or event handlers. Instead, every request is routed to a method called an action. An action may return a static page, a page with data, raw data (xml, json, csv, etc), modify your model, or pretty much anything else you can think up.

Action Filters

Action filters are truly the most powerful part of the MVC framework. WebForms has nothing similar. Action filters allow you to intercept requests before and after the controller action executes. Filters make up probably 80% of the functionality in my applications. Some things I use them for are:

· Authorization/security checking

· Sorting and paging data sets

· Injecting static data (so I don’t have to manually populate my drop downs)

· Injecting menus into every page

· Input validation

· Workflow control (after saving on an edit screen I auto redirect back to the list page)

· Exception handling

· Dynamically associating an action with a view

· Data transformation (raw data collections to json, csv, xml, pdf, etc)

Action filters are basically unlimited in what you can do with them. I’m sure developers will be finding new uses for them all the time. Check out Wes McClure’s blog for some interesting ideas on automating the use of filters.

Model Agnostic

MVC doesn’t care how you create and persist your model. You can use LinqToSql, Entity Framework, NHibernate (my favorite ORM), raw SQL (please don’t!), web services, or anything really. There are no controls tying you to a specific Microsoft data technology. I’ve spent too many days hacking apart ObjectDataSources to work with anything besides a dbml.

Automated input mapping

MVC provides model binders which convert incoming request data (query string or form posts) into whatever type of object you specify. Many examples online demonstrate binding directly to your data model however you should be aware of the associated risks. MVC will not stop you from exposing dangerous security holes. This is something many WebForms developers are not used to thinking about. Don’t be scared by this though, there are several best practices available to eliminate these risks.

Full control over rendered output

When you create a page (called a view) in MVC, you are dictating the raw HTML output. The default syntax is very ASP-like, scattered with many beestings. (<% … %>) Because MVC was designed MVC to be highly modular you can swap out the default ASP.NET view engine with one of the many other available engines. I prefer the Spark View Engine because it provides a very concise HTML-like syntax. It also allows you to write macros which are HTML based scripts that reduce the amount of markup you need to write.

MVC also provides Html Helper methods, which reduce the need to write common HTML tags. Some examples are Html.Button(“Save”) and Html.TextBox(“name”, Model.Name). Html helpers are simply extension methods so it is very easy to write your own.

No Surprises

The built-in controls in WebForms are guilty of surprising behavior. My favorite example is the asp:Panel control which renders as a div until you set the GroupingText property. Then it becomes a fieldset. Surprise! Hope your css didn’t break.

Convention over Configuration

This is my favorite part of MVC. Although it isn’t available “out of the box”, because MVC is so flexible it is easy to add your own features. I have adapted FubuMVC’s Html convention feature to work with Microsoft MVC. This allows me to have dynamic inputs. Instead of writing Html.TextBox(“name”, Model.Name), I can instead do Html.Input(m => m.Name) and allow the framework to use my conventions to determine that Name should rendered as a text box. MVC 2 will provide similar functionality (with Dynamic Data and templating), but I prefer the Fubu approach because it gives you much more control than even a template would. Expect a post with details about this soon.

True AJAX support

Since actions are not required to return HTML, you can use them to return raw data as JSON for AJAX. MVC even comes with JQuery right in the default project. There is no fake postback, like in WebForms, to render partial views. Since MVC is stateless I use AJAX forms to provide the illusion of state to the user.

Testability

Many people promoting MVC are also promoting TDD and testability. This is because MVC almost encourages unit testing. Unlike many people, I’m not going to encourage testing your controller actions, but the ability to is there. Microsoft listened to the community and provided interfaces for nearly everything in MVC so you can stub away if you please.

Because MVC is not only a framework but also a pattern, it is my hope that developers who are not familiar with patterns will learn more about them while learning MVC. My goal for this blog is to help lower the barrier or entry to MVC with real work examples and to promote pattern oriented development.

This all sounds great, but what are the disadvantages? Businesses that have investments in WebForms may not want to switch any time soon for many reasons.

Small, vocal user base

Although it may sound like WebForms development is over, we MVC developers are still a very small, albeit vocal, minority. Despite being small, it is very easy to find people in the MVC community willing to help you learn. Many members of the MVC team at Microsoft are very active in the community and there is no shortage of bloggers willing to answer questions.

No designer support

Developers who are used to drag and drop probably won’t welcome switching to a framework with no concept of a designer. Everything in MVC is hand written, at least in my experience.

Lack of third party tools

There are thousands of third party tools available for WebForms and many companies have invested in them. The MVC community does not have nearly as many tools available. However there are a lot of free JQuery plugins available for grids, select boxes, calendars, etc. You will find yourself writing a lot of javascript with MVC if you want AJAX. JQuery is one more library that developers will need to become familiar with when switching from WebForms.

I’m sure that there are many advantages and disadvantages that I have overlooked, but I hope this gives you an idea of how MVC compares to WebForms and why you might want to check it out.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Saturday, February 13, 2010 #

Here is an example of a case in which I wanted to overload a Spark macro to display two input elements in one table row.

<table>
   !{Row(x => x.Name)}
   !{Row(x => x.Description)}
   !{Row(x => x.Price)}
   !{Row(x => x.SaleStartDate, x => x.SaleEndDate)}
   !{Row(x => x.SaleDiscount)}

   <tr>
          <td></td>
           <td>!{Html.SubmitButton("Save")}</td>
    </tr>
</table>

<macro name="Row" expression="Expression[[Func[[ProductViewModel, object]]]]">
    !{Row(expression, null)}
</macro>

<macro name="Row" expression="Expression[[Func[[ProductViewModel, object]]]]" expression2="Expression[[Func[[ProductViewModel, object]]]]">
    <tr>
           <td>!{Html.LabelFor(expression)}</td>
           <td>!{Html.InputFor(expression)} 
                   <if condition="expression2 != null">
                           !{Html.InputFor(expression2)}
                   </if>
           </td>
    </tr>
</macro>
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Wednesday, February 10, 2010 #

I was recently having a discussion with @tyarmer and @g0t4 about what is necessary to sufficently test a method that determines the previous business day. There are quite a few unique scenarios that can come up. Here are a few:

  • On a weekend, you should get Friday, unless it’s a holiday.
  • On a Monday you should get Friday, again unless it’s a holiday
  • If a day is holiday you should get the day before, unless that’s a holiday and a weekend
  • And so on… Obviously there’s a bit of a pattern here

I suggested that if we used a recursive implementation, such as follows, it would only be necessary to test a Saturday, Sunday, Monday, and the day before a holiday—one test per code path. @g0t4 countered that our tests should be independent of the implementation. Also we should at least smoke screen a more complex scenario.

public DateTime GetPreviousBusinessDay(DateTime date)
{
	var previousDay = date.AddDays(-1);
	if (previousDay.DayOfWeek == DayOfWeek.Saturday || previousDay.DayOfWeek == DayOfWeek.Sunday || IsHoliday(previousDay))
	{
		return GetPreviousBusinessDay(previousDay);
	}
	return previousDay;
}

I agree with that assessment. We then decided to see how my tests would compare to an iterative implementation of the function.

public DateTime GetPreviousBusinessDay(DateTime date)
{
	var previousDay = date.AddDays(-1);
	while(previousDay.DayOfWeek == DayOfWeek.Saturday || previousDay.DayOfWeek == DayOfWeek.Sunday || IsHoliday(previousDay))
	{
		previousDay = previousDay.AddDays(-1);
	}
	return previousDay;
}

Alright, so far so good. Looks like we’d still have 100% code coverage. However, in comparing the two methods we realized that there are actually two operations going on in both these implementations. The first operation is really just iteration over a decending list of days. The second is checking whether or not that day is a business day. Of course at this point we couldn’t help but decide that we needed to test these operations separately. Thus we decided to generate an enumeration (calculated on demand) for the days and have a separate function that determines if it’s a business day. So now we have:

public class HistoricalDates
{
	public static IEnumerable<DateTime> StartingFrom(DateTime start)
	{
		yield return start.AddDays(-1);
	}
}

public class BusinessDates
{
	public DateTime GetPreviousBusinessDay(DateTime date)
	{
		return HistoricalDates.StartingFrom(date).Where(IsBusinessDay).First();
	}

	public bool IsBusinessDay(DateTime date)
	{
		return !(date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday || IsHoliday(date));
	}

	public bool IsHoliday(DateTime date)
	{
		// ....
	}
}

Clearly, quite a bit more code, but we’ve managed to separate our concerns. Another cool thing about this code is that it is now very simple to expand on the intial method. Say you needed a method to determine three business days ago. Now we can leverage Linq to manipulate our “collection”.

public DateTime GetThreeBusinessDaysAgo(DateTime date)
{
	return HistoricalDates.StartingFrom(date).Where(IsBusinessDay).Skip(2).First();
}

You could also use the Take() method to generate a series of days matching your condition.

public IEnumerable<DateTime>GetFivePreviousBusinessDays(DateTime date)
{
	return HistoricalDates.StartingFrom(date).Where(IsBusinessDay).Take(5);
}

I think this is amazingly simple. Doing either of these types of calculations with the iterative or recursive implementations would have taken much more work and be much more likely to have a bug. By thinking with collections we were able to turn our somewhat complicated scenarios into simple Linq operations. Now that I’ve seen how simple this was I’m going to be watching out for more scenarios that could benefit from being broken into an enumerator and a condition.

Finally, here is our current implementation as expanded to include enumerating in both directions.

public class Dates
{
	public static IEnumerable<DateTime> BackwardsFrom(DateTime start)
	{
		yield return start.AddDays(-1);
	}

	public static IEnumerable<DateTime> ForwardsFrom(DateTime start)
	{
		yield return start.AddDays(1)
	}
}
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati