First time here? You are looking at the most recent posts. You may also want to check out older archives or the tag cloud. Please leave a comment, ask a question and consider subscribing to the latest posts via RSS. Thank you for visiting! (hide this)

August 2009 Blog Posts

Lucene.net: the main concepts

In the previous post you learnt how to get a copy of Lucene.net and where to go in order to look for more information. As you noticed the documentation is far from being complete and easy to read. So in the post I’ll write about the main concepts behind Lucene.net and which are the main steps in the development of a solution based on Lucene.net.

Some of the main concepts

Before looking at the development phases, it’s important to have a look at the main actors of Lucene.net.

Directoy

The directory is where Lucene indexes are stored: it can be a physical folder on the filesystem (FSDirectory) or an area in memory where files are stored (RAMDirectory). The index structure is compatible with all ports of Lucene, so you could also have the indexing done with .NET and searched with Java, or the other way around (obviously, using the filesystem directory).

IndexWriter

This component is responsible for the management of the indexes. It creates indexes, adds documents to the index, optimizes the index.

Analyzer

This is where the complexity of the indexing resides. In a few words the analyzer contains the policy for extracting index terms from the text. There are several analyzers available both in the core library and in the contrib project. And the java version has even more analyzers that have not been ported to .net yet.

Probably the analyzer you’ll use the most is the StandardAnalyzer, which tokenizes the text based on European-language grammars, sets everything to lowercase and removes English stopwords.

Another interesting analyzer is the SnowballAnalyzer, which works exactly like the standard one, but adds one more step at the end: the stemming phase, using the Snowball stemming language. Stemming is the process of reducing inflected words to their root. For example, if you are looking for “developing”, probably you are also interested in the word “developed” or “develop” or “developer”. During the indexing phase, the stemming process normalizes all these inflected words to their root “develop”. And does the same when querying the index (if you search for “development” it will search for “develop”). Obviously this is tied to the language of the text, so the snowball analyzer comes with many different “grammars” for that.

Document and Fields

A document is a single entity that is put into the index. And it contains many fields which are, like in a database, the single different pieces of information that make a document. Different fields can be indexed using different algorithm and analyzers. For example you might just want to store the document id, without being able to search on it. But you want to be able to search by tags as single keywords, and, finally you want to index the body of blog post for full text search (thus using the Analyzer and the tokenizers).

Since this is an important topic, I’ll write a more in depth post in the future.

Searcher and IndexReader

The searcher is the component that, with the help of the IndexReader, scans the index files and returns results based on the query supplied.

QueryParser

The query parser is responsible for parsing a string of text to create a query object. It evaluates Lucene query syntax and uses an analyzer (which should be the same you used to index the text) to tokenize the single statements.

The main development steps

And now let’s have a brief overview at the logical steps involved in integrating Lucene.net into your applications:

1 – Initialize Directory and IndexWriter

The first step is initializing the Directory and the IndexWriter. In a web application, like Subtext, this is most likely done in the application startup and then the instance stored in a global variable somewhere (or accessed through a Singleton) since only one Writer can read the Dictionary at the same time.

And when you create the IndexWriter you can supply the analyzer that will be used by default to index all the text.

2 – Add Documents to the Index

Each document is made by various Fields. You have to create a Document with all the Fields that must be indexed and also the ones you need in order to link the result to the real document that is being indexed (for example the id of the post).

And once created the Document, you have to add it to the Directory with the IndexWriter.

At this point, you could either add more documents or close the IndexWriter. The index will be saved to the Directory and can be re-opened later for adding more Documents or to perform queries on in.

3 – Create the Query

Once you have all your documents in the index, it’s time to do some queries.

You can create the query either via the QueryParser or creating a Query object directly via API.

4 – Pass the Query to the IndexSearcher

And once you have the Query object you have to pass it to the Search method of a IndexSearcher.

One caveats is that the IndexSearcher sees the index only at the point it was at the time it was opened. So in order to search over the most recent set of documents you have to re-open the IndexSearcher. But re-opening takes time and resources, so in a web application you might want to cache it somehow and re-open it periodically.

5 – Iterates over the results

The Search method returns the results, inside a Hit object, which contains all the documents that match the query, ordered by Score, which is a very complex math formula that should tell you how much the document found is related to your query. For more information refer to Lucene website: Scoring.

6 – Close everything

And once you are done with everything, close the IndexWriter, IndexSearcher and the Directory object. In a web application this is typically performed in the application shutdown event.

Next

You just read about the main concepts behind Lucene.net. In a future post I’ll write how to implement Lucene.net into a sample console application that puts together all the concepts discussed here.

Feel excited: got my copies of my book Beginning ASP.NET MVC

Our book is out in the wild since almost a month, and many people out there already received their copies, some also wrote reviews of the book and even had parties to present the book, but I didn’t have the pleasure to hold in my hands a real copy of the book till this morning (yeah, I know, Italian post is very slow delivering parcels).

And being my first book I’m very excited and pleased to see the real thing, and to see my face on the its cover.

How to get started with Lucene.net

lucene_net_green_460

A few weeks ago I expressed my intention of introducing Lucene.net into Subtext, and that I would have written about the journey. In this post I’m going to write some hints on how to get started with Lucene.net.

Download the bits

Unfortunately Lucene.net is not officially releasing new versions since March 2007 when Lucene.net 2.0 was released. But since 2007 a lot of new features and bug fixes where introduced, so the best way to get the latest bits is to download the latest tag of the SVN repository. At the time of writing the latest tag is version 2.3.2. This is also the recommendation of the developers since “bureaucracy” is preventing the official release to happen.

And then, once you got the latest bits from the Subversion repository, you have to start the build process. The solution file available in the repository is still with VS2005 so either you use that version, or run the file through the update wizard and use VS2008.

The structure of the repository is quite deep, so it’s worth to have a few words on it before going on:

  • src: contains 3 subfolders with the source for the core library, the unit tests and a few demo project that are interesting to show the main usage scenario
  • contrib: this contains a few external libraries that enhance the feature of Lucene. There is a small utility class that helps highlighting the matching terms, there is another lib that helps building similarity queries, there is spellchecker, there are stemmers (a “thing” that normalizes the text to be indexed) and there is also a distributed search engine

I hope the developers of Lucene.net find a way to publish an official updated release because seeing a 2 years old release might frighten people and make them think that this project is not maintained any more.

Or alternatively you can skip to the end of this post and download the assembly I built to make life easier for you.

Now that you’ve got a binary version of Lucene.net the next step is learning how to do it. I’m going to write some more posts on this in the next weeks, but if you want to start reading directly from the original documents, in the next section you’ll find where to go.

Find the documentation

Documentation is probably the thing that is lacking the most in this project (and this is one of the reason why I decided to write this series of posts). But being a class-by-class port of the Java version, you can find a bit more information on the Lucene for Java website (but just a bit).

I would suggest starting from the overview available in the JavaDoc, which explains the main packages and a basic usage scenario. And then go for the MSDN-style documentation for Lucene.net (but be careful since it’s related to Lucene.net 2.1). And some more unstructured documents are available in the wiki.

Finally, if you want to get deeper into Lucene, a book from Manning is available: Lucene In Action. It’s a bit old and talks about Lucene 1.4. But most of the key concepts are still the same. There is also the second edition of the book, still in MEAP: Lucene in Action, Second Edition. But it talks about the forthcoming version 3.0, so a bit too much if you are interested in Lucene.net which is still at version 2.3.

That reminds me of how important a good documentation is for opensource projects: even if you built the best OSS library in the World, if it’s not well documented all your efforts are useless. But that’s probably a topic for another post.

Next

Now you know how to get Lucene.net and where to look to find more information. In a future post I’ll write about the main concepts of Lucene.net and later about how I’m implementing Lucene.net into Subtext.

If you trust me, and want to avoid all the hassle of getting the source from SVN, migrating the solution to VS2008 and build it, I did it for you, and you can download the main Lucene.net 2.3.2 library.

 

CKEditor 3.0 is out

logoAfter a long period of development, the new major release of FCKEditor has shipped.

The most notable change is the new name: it went from FCKEditor, which many people didn’t like because of its similarity to an English bad word (it was made by the initials of the project founder, Frederico Caldeira Knabben) to CKEditor where CK stands for “content & knowledge”.

But obviously this is not the only change: it’s amazingly fast, it has a completely new UI, no more popup but only js modal dialogs, produces valid XHTML code (and hopefully it will not screw-up the code snippets written with WLW) and much more. Read the official release note to know more: CKEditor 3.0 is here!

And also I recommend playing with the demo for more complete experience. It’s impressive!

At the moment there is no server-side integration like it was with FCKEditor 2.x, but given the very easy Javascript API this is not a big deal. But the really missing feature is the lack of an integrated file/image browser: if you are building a closed source project you use the other product built by CKSource, CKFinder, which is a very powerful file browser. But unfortunately it doesn’t come with an opensource license: this prevents the usage of CKEditor in opensource projects like Subtext and DotNetNuke.

They say there will be a trimmed-down CKFinder with CKEditor 3.1 but until then, don’t expect to see CKEditor integrated with Subtext.

Scheduling post while on vacation: how did it go?

As you might have noticed if you followed my twitter stream, I spent the last two weeks in Hokkaido, doing some trekking and enjoying the onsen. But still 5 new posts appeared on my blog. This happened thanks to a feature of Subtext that allows posting in the future.

Before leaving to Japan I was undecided about scheduling posts while I was on vacation for two weeks, but then I decided to try this experiment.

But now I’m back and I wanted to ask you what you think of what I did: did you like the fact that I new posts were appearing? Or do you think my vacation would have been unnoticed? Or maybe you think I should have just stopped writing posts since I was not available to respond to comments. Please let me know your thoughts by answering the following poll, and by writing a comment. Thank you.

And now the link to the poll: The posts on the last 2 weeks were scheduled: what do you think of the experiment? Should I schedule posts next time I'm away for long time?

Code Rush: when making software was fun

Not that now making software is not fun anymore, but working on a startup, trying to make something that might change the way we think at software, or making something totally new is much more fun than… everything else that doesn’t involve working with “startups”.

And this spirit is well capture into Code Rush, a documentary about the open-sourcing on Netscape and beginning of the Mozilla Project: featuring the first nightly build, the launch party and much more. It was first released in VHS (we are talking about 1998), when out-of-print, and at the end of July 2009 Code Rush was released with a Creative-Common license, and you can download it for free in various format. But there is more, they are putting up online all the recorded footage (105hr) in a searchable archive.

This a very particular moment in the history of computers, but we must remember that making software is fun, and even if we are maintaining a legacy application we have to try and find the fun hidden into it.

[Via Startup, when programming was still fun]

PS: OK, working for startups have disadvantages as well, but still… fun.

11 books for a .NET Summer reading list

Now that my book is on shelves, I’m out of things to do when I come back from work. Furthermore during this year I bought or I was given quite a few interesting programming book, so I think I’ll start using my spare time to improve my skills.

Here is the list of books I’m going to read, some of which I think are a must read for all .NET developers.

Frontend development and JavaScript

I’m a web developer at heart, and I truly believe that a web developer must know everything about Javascript, CSS and HTML. One must not be a guru of them, or a good designer, but must know the techniques behind the so-called front end technologies. So, here are some of the books in my reading list:

Even Faster WebSites

Even Faster WebSites is the second book of the series (the first book was High Performance WebSites) written by Steve Souders, that explains how to improve the performances of a web site, looking at them from the standpoint of the user experience. So it shows how to optimize javascript, how to optimize images, CSS and so on. I read the first book and really recommend it. And I also started skimming through the other book: I think it’s a must read book for everybody working on public-facing sites and on intranet applications with lots of users spread through the globe (and not all in the same LAN)

Pro Javascript Techniques and Secret of the Javascript Ninja

These two books, written by John Resig, are a kind of brain dump of John’s brain: they show advanced uses of Javascript, and how to build your own javascript library. Probably you are not going to write one yourself, but some of the concepts, like closures and advanced cross-browser detection is something you can apply anywhere.

The first book Pro Javascript Techniques, is bit old (end of 2006) but it still contains lots of information on writing OO javascript: it also encapsulate the knowledge John was putting into his brainchild, jQuery.

Secret of the Javascript Ninja is still in early preview access, and you can get the access to the early drafts on Manning site. It’s planned to be released in November 2009.

jQuery in Action

This is THE jQuery book. I already read it last year, and now the second edition is on MEAP on Manning. It will be about jQuery 1.4 and jQuery UI. How can it be about jQuery 1.4 which has not been released yet? The authors are helped by Mr. John jQuery Resin in person. So, if you want to know what’s going to happen with jQuery, this is another must-read book.

Architecture and Methodologies

Lately I’m really getting into methodologies. Unfortunately, for various reasons, I’ve really never been able to apply the full agile principles and practices in a “real” project. But here are some interesting books that might help me find a way to convince my managers and customers to fully embrace Agile.

Art of Unit Testing

Written by Roy Osherove, this is the book I’m bringing with me during my trip in Japan (which, thanks to Subtext future publishing feature, is happening right now while you are reading this post). It’s only 300 pages long so it fits well into my backpack. It’s not the usual book about unit testing: what I really liked about it is that it not only explains you the techniques of unit testing, but tells you real world examples of how unit testing can be introduced into your company, and ways to convince your boss to let you do testing.

The best part is the one that shows a survey done by a software company: same features, two different teams. One team writing test, the other not writing.

The team writing tests took 14 days to implement the feature, while the one not writing took only 7 days (obviously, if you write tests, you write double the code). Then the integration phase took 2 days with tests, and 7 days without tests. And then, the testing and fixing took 12 days for the ones that didn’t write test, and only 8 for the one with tests.
The overall time taken was 24 days for the team that wrote tests and 26 days for the team without tests, which is 2 days more. But the astonishing thing is that 73 bugs were found in production for the feature implemented without tests, and only 11 for the team that wrote test.
(This is not an actual quote from the book)

This is just an example of the real world experience that Roy put in his book. Another must-read book for your summer evenings.

Agile principles, practices and patterns in C#

Written by UncleBob (aka Robert C. Martin), this is the Bible of Agile development. It talks about all the practices of Agile: TDD, refactoring, pair-programming, incremental builds, SOLID principles and lot more. And the best part of it is that everything has samples in C#, and not in Java as most other books about Agile. Unfortunately this is bigger and heavier then the one by Roy. And probably a bit too complex as vacations time reading. But really, really, really recommended.

Architecting Applications for the Enterprise

Written by friend and community fellow Andrea Saltarello, this is not about Agile or testing in particular, but is about all the aspects related to building a real world application: patterns, architectural thoughts (either software and hardware), development methodologies, testing, tracing, and so on.

.NET Development

I’m still a .NET developer, and I still need to write some code now and then. But I usually learn the libraries once I need them. But these two books are still interesting for forming a background.

ASP.NET MVC in Action

Since I wrote a book about ASP.NET MVC you might wonder why I’m reading another book on the same topic. The reason is that this book is written with a pretty interesting plot: it’s based on the real world development of CodeCampServer. And also, there is always something to learn from Jeffrey Palermo and Ben Scheirman.

Professional LINQ

LINQ is a strange beast, and I still haven’t used it further than the simple usual queries. This book gets deeper into the some more advanced features, and also shows how to write a simple custom LINQ provider

NHibernate in Action

I’m not a bit data-layer guy, and I always focused most of my attention and interest in the UI layer side of applications. When I built my last complete application a few years ago I used NHibernate, but I did it the naive way. This book is the Bible of NHibernate. A must read for everybody that wants a well paced and well organized way of learning this powerful ORM.

Wrapping up

Will I be able to read all that books before I embark in another adventure? Only time will tell. But in the meantime, I hope you found my recommendations useful.

How to use Ninject 2 with ASP.NET MVC

Back in February I wrote a series of posts about Ninject and ASP.NET MVC, and how to adapt Ninject v1 to inject dependencies into ActionFilter. Now that Ninject 2 reached the Beta status and a final release could be on its way, I think the time has come to to update the article. So in this post you’ll learn how to use Ninject v2 to inject dependencies into ASP.NET MVC controllers and action filters.

What’s new in Ninject 2

Ninject 2 has been rewritten from scratch, trimmed down a lot, many non-core features removed, and a plugin/extension model has been introduced. You can read more details about the new features on Nate’s blog. The main change that impacts the integration with ASP.NET MVC is that it is now in its own project, called Ninject.Web.Mvc, and that it now includes filter injections by default. So no more need of the small utility I developed to support injection into ActionFilters.

Where to get Ninject 2

Ninject v2 has not been released yet: the sample on this post is based on the official beta released by Nate, but if you want you can download the latest source code directly from the repository online:

The zip files are just the dump of all the tree in the repository. Once you download them, you have to extract and then build the two project.

But if you don’t want to go through all that process, the code sample attached to this post contains the beta version of Ninject core and of the ASP.NET MVC extension.

Application code

This sample is just going to be the port of the sample I wrote for Ninject v1:

  • Controller that calls an external service to get the Greeting
  • Actions decorated with the attribute that sets the title of the page
  • View that shows the greeting to the user

For your convenience here are some snippets with the parts of the code that are relevant for the sample.

The external greeting service

First is the external service, which returns the greeting to the visitor of the site

public class GreetingServiceImpl : IGreetingService
{
    public string GetGreeting()
    {
        return "Hello from the Greeting Service concrete implementation!";
    }
}

public interface IGreetingService
{
    string GetGreeting();
}

The HomeController

What the controller does is just calling the service and putting the greeting returned inside the view model. Also the action is decorated with an ActionFilter that sets the title of the page, always retrieving it from the same greeting service.

public class HomeController : Controller
{
    private readonly IGreetingService _service;
    public HomeController(IGreetingService _service)
    {
        this._service = _service;
    }

    [TitleActionFilter]
    public ActionResult Index()
    {
        ViewData["Message"] = _service.GetGreeting();
        return View();
    }
}

The action is decorated with the TitleActionFilter attribute

The TitleActionFilterAttribute

public class TitleActionFilterAttribute : ActionFilterAttribute
{
    [Inject]
    public IGreetingService _service { get; set; }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        ViewResult result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.ViewData["Title"] += _service.GetGreeting();
        }
    }
}

The property that contains the reference to the external service, and that will injected via Ninject, is decorated with the [Inject] attribute

The view

And finally the view, whose only purpose is displaying the message to the user and setting the title of the page.

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    <%= Html.Encode(ViewData["Title"]) %>
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData["Message"]) %></h2>
</asp:Content>

But now let’s have a look at how to setup Ninject v2 with ASP.NET MVC

Wiring up Ninject

Since version 1 and even 1.5, a lots of improvement were added, so the steps for setting up Ninject in an ASP.NET MVC project with support for injection into ActionFilters went down to just 2:

  1. Add the references to Ninject and Ninject.Web.Mvc
  2. Setting up the container inside the Global.asax.cs file

Let’s see each one of these steps.

referencesAdding references

After you downloaded the assemblies or compiled the source from GitHub, you have to add the two assemblies are references:

  • Ninject
  • Ninject.Web.Mvc

Copy them into a folder inside your solution and add the references.

Setting up the container

This step is the one that differs the most from version 1.5 of Ninject.

You still have to inherit from NinjectHttpApplication instead of HttpApplication, but the way you register the controllers is different.

Here is the complete code of the Global.asax.cs file:

public class MvcApplication : NinjectHttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        //Here goes routing setup
    }

    protected override void OnApplicationStarted()
    {
        RegisterRoutes(RouteTable.Routes);
        RegisterAllControllersIn(Assembly.GetExecutingAssembly());
    }

    protected override IKernel CreateKernel()
    {
        return new StandardKernel(new ServiceModule());
    }
}

internal class ServiceModule : NinjectModule
{
    public override void Load()
    {
        Bind<IGreetingService>().To<GreetingServiceImpl>();
    }
}

All the initialization code of the web application, the one that would normally go into the Application_Start method, now has to go into the OnApplicationStarted one. Inside this method goes the setup of the routing table and the call to the method that registers all the controllers of the application.

RegisterAllControllersIn(Assembly.GetExecutingAssembly());

This method scans all the types inside the assembly supplied, and registers for injection all the controllers it finds.

The Ninject Application class also makes easier creating and configuring the kernel, through the CreateKernel method.

And what about the ActionFilters?

You might wonder where all the configuration needed for injecting dependencies inside action filter went. The cool thing about Ninject 2 is that this kind of injection comes out of the box with the ASP.NET MVC extension. So the only line of code needed it the [Inject] attribute applied to the property of the action filter that will hold the injected dependency. Cool, isn’t it?

What’s next

Ninject v2 is looking very stable, and I’ve used it in production code, and didn’t give me any problem, so I really encourage you download the latest bits, and play around with it.

If you want to try this by yourself, I packaged the sample into a VisualStudio 2008 solution that you can download

kick it on DotNetKicks.com

IE6 no more

ie6-no-more.jpg

In February I joined the "IE6: Do NOT want!" campaign, which was started by some big media sites in Norway: I was planning to remove the script that showed more modern browsers to the user after one week, but I kept it till now.

Probably not because of me joining the campaign, but IE6 is slightly dropping. I only have stats for my blog, but the percentage of users running IE6 dropped to 8.5% of January, to the 6.4% of July.

But still it's not enough: IE6 is a 8 years old browser, there is no reason to keep on using it. How many of you are still using a PC bought in 2001?

Many web developers are already dropping support for IE6 (like Nate Kohari, owner of Agile Zen, said in his latest interview on HerdingCode), but for less niche websites IE6 is still a browser developers have to support. So, to try and put an end to this pain, a few days ago some popular web startups started another, and, giving their reach, hopefully more effective campaign: IE6 no more.

It works like the other one, but with a much nicer banner:

IE6NoMore.jpg

As a Digg survey found out, the majority of "corporate" users (users that browser the web from their workplace) are still running IE6 because the IT admins prevent them from upgrading. That means that telling them to upgrade is pointless: but if some CEO sees his favorite web site with the warning, probably he might ask the IT department to upgrade the browsers. Anyway, for more informations on how "corporate" users might workaround their restrictions, the campaign's site gives some interesting hints.

How to create a DropDownList with ASP.NET MVC

The DropDownList html helper differs a bit from the standard Html helper methods, and, not surprisingly, the way it works is one of the questions I get asked the most. So in this post I’m going to dissect this method, and show you how to use it.

Standard Html Helpers

One of the cool features of ASP.NET MVC is the automatic binding of html form fields: all the Html helper methods will auto-magically take the default value of the form field directly from the ViewData or the view model object with the same name of the control.

Calling the TextBox helper method:

<%= Html.TextBox("Name") %>

will results, if the view model supplied contained the property Name, in the following HTML:

<input id="Name" name="Name" type="text" value="Simone" />

It would have been the same as calling the other helper overload, which specifies both the name and the value:

<%= Html.TextBox("Name", Model.Name) %>

Introducing the DropDownList helper

But things get a bit more complex when it comes to the HTML Select element, which most ASP.NET developers know as DropDownList. This control needs two values to be retrieved from the ViewData: the list of items to be displayed in the drop down, and the item that needs to be pre-selected, so the code to set it up is a bit more complex.

The automatic binding of the other html helpers still works but, since it can bind only one thing at the time, depending on your preferences you have and the scenario you are facing, you have to decide whether you want to automatically bind the list item or the selected item.

The method signature

Let’s have a look at the method signature:

Html.DropDownList(
string name,
IEnumerable<SelectListItem> selectList,
string optionLabel,
object htmlAttributes)

and the meaning of the parameters:

  • name – the name of the HTML select element, and also the name of the view model property that is bound to the element
  • selectList – the list of options of the select list
  • optionLabel – the text that will be added at the top of the select list. Usually something like “Select …”
  • htmlAttributes – this is in common with all the other html helper. A dictionary or an anonymous type with the html attributes you want to add to the HTML element

All the parameters except the first one are optional: if only the name is provided, the helper will automatically bind the list item. Otherwise if both the name and selectList are provided, the select item will be bound, and the select list will be the one supplied with the parameter. You’ll see how to adopt each approach later.

The SelectListItemClass

But now let’s have a look at the presentation model class used to represent the drop down list with its options: SelectListItem.

This class has three properties:

  • string Text – the string that will be displayed as text of the option
  • string Value – the string that will be used as the value of the option
  • bool Selected – whether the option is selected

How to write a DropDownList

Let’s now have a look at the two possible way of building a DropDownList.

Autobinding the ItemList

The first approach consists in setting up the whole list of items in the controller, specifying also which options must be the selected item.

List<SelectListItem> items = new List<SelectListItem>();
items.Add(new SelectListItem
{
Text = "Swimming",
Value = "1"
});
items.Add(new SelectListItem
{
Text = "Cycling",
Value = "2",
Selected = true
});
items.Add(new SelectListItem
{
Text = "Running",
Value = "3"
});

As you can see, you set the text and value for each option, and set Selected = true for the item you want to be selected. And then you call the helper, specifying only the name: this will be the name of the select element, and must be the same name of the property of the view model that contains the list of items (in the sample named ListItems).

<%= Html.DropDownList("ListItems") %>

But in case you are caching the list of items or are retrieving them separately from the item that must be selected this is not the best solution.

Autobinding the selected item

The other approach is to automatically bind the selected item, and passing the list of items as parameter to the DropDownList helper method.

In the controller you do exactly the same thing as before, just don’t set to true the Selected property of any item. Then you also have to put into the view model the value of the item you want to select.

var model = new IndexViewModel()
{
ListItems = items,
SelectedItem = 2
};

And finally in the view, you use the overload which accepts also the selectList parameter:

<%= Html.DropDownList("SelectedItem", Model.ListItems) %>

The only difference in the HTML rendered is that, with first approach, the name of the HTML select element is “ListItems”, with the second it is “SelectedItem”.

These approaches are fine if you are creating your own list, but they are not the optimal solution if you are receiving the list of options for an external method, for example from a DB repository.

Using the SelectList helper class

To address the latest scenario the ASP.NET MVC framework comes with a class that helps you build the list of items in a way that can be accepted by the DropDownList html helper: it’s called SelectList.

This class encapsulates all the information needed to create a list of SelectListItem:

  • Items – any IEnumerable containing the list of items that needs to be in the select element
  • DataTextField and DataValueField – the names of the properties that will be used as text and as value of the item
  • SelectedValue – the value of the selected item

Using this you can take any list of objects and turn it into a list of SelectListItem

//with selected value specified
var selectItems = new SelectList(brands, "BrandId", "BikeBrand", 2);

//only the items list var selectItems = new SelectList(brands, "BrandId", "BikeBrand");

And you can use it either specifying the selected value in the controller, and using the overload with just the name parameter, or specifying the selected value as additional property in the view model and using the overload that takes both the name and the selectList property (same as the first two approaches).

Wrapping up

In this post we dissected the DropDownList API, and you saw the different possible approaches to writing a dropdown list:

  • Specifying all the info needed (list of options and selected option) inside a List of SelectListItem and passing it to view: this is a good solution if you build the list and you can set the selected item at the same time and in the same process
  • Put the list of options as a List of SelectListItem and the Selected Item in two separate properties of the view model: this approach is better if you build the list and retrieve the selected item in different moment and/or in different processes
  • Use the SelectList helper class to create the needed list: use this approach if you receive the list of items for a external library and you don’t want to manually cycle over it to create the List of SelectListItem

Hope this post helped clearing up a bit the confusion that I saw around the DropDownList helper method.

For a more samples about creating a DropDownLists with ASP.NET MVC, and all other HtmlHelper, I'd recommend the book I wrote about ASP.NET MVC, titled Beginning ASP.NET MVC 1.0, published by Wrox

kick it on DotNetKicks.com

Beginning ASP.NET MVC 1.0 available on Amazon

BeginningASPNETMVCv1_3.jpgIt's been a long journey, that started more than one year ago: today our Beginning ASP.NET MVC 1.0 book is available for purchase on Amazon US.

Probably some of you, the ones which pre-ordered the book, will be receiving it soon. And in a few days (probably next week), the book will be officially available also on Amazon UK (still in pre-sale now) and later this month also on physical bookstores.

If you want to have a look at what's inside the book, you can download the free chapters we made available last month, or you can just go on Amazon and click on the "Look Inside" link to read chapter 1 about the Model View Controller pattern, the detailed Table of Contents and the Index.

And now that the book is officially out, I want to thank all the people that helped and supported me during the book writing process: my wife Daniela, my friends, Keyvan for the invaluable suggestions and for sharing his experience, Kelly and Sydney - our development editors, Katie and Paul - the marketing guys, Ivan, Eilon and Phil for their suggestions and comments, and Jim for being a great manager and making all the issues easier than they were.

And obviously a big thanks goes also to my colleagues and managers in Avanade (both Italy and in the US), the development team of the clients I worked for during this last year and the guys in the community. Thank you all for the encouragement and the support.

Without any of you this book would have not seen the shelves.

Microsoft vs HP: different approaches to recycling

In the last two weeks I got three packaging that made me thing the way products are packaged, and how with a little bit of care, industries could make lower impact on environment

The Facts

HP printer cartridge

Today I bought a cartridge for my HP printer, and I was positively surprised by how much HP cares about recycling.

The package is all cardboard, plus a thin aluminum wrap around the cartridge itself, and enclosed in the box there is a prepaid and self-addressed envelope where I can put the old cartridge in and sent it back to HP for recycling.

cardridge_packaging.JPG cardridge_evenlope.JPG

Microsoft Points prepaid card

Then I received an XBox Live points card: it's a plastic, credit card sized, enclosed in a plastic box like the ones used for DVDs, with a plastic cover, and all wrapped in thin plastic foil. All this plastic for just a 25 digit code.

microsoft_points_cover.JPG microsoft_points.JPG

Chinese Brand SD

Still, not as bad as the packaging for a chinese brand SD card I bought last week: a big thick plastic enclosure with a strange screw cover.

More plastic packaging than the Dell 27" Display I bought last month.

Who is the winner?

Obviously HP is the winner: only cardboard and a pre-paid envelope to make you want to recycle the used cartridge.

Then, far behind is Microsoft: a lot of plastic (even if it seems to be recyclable plastic) just for a digit. Couldn't have they just sold the card with the printed digits in small warp? Like all the mobile phone prepaid card? This would reduce production costs, recycling costs and environmental costs.

And far far far behind, is the chinese brand SD card, with no recyclable packaging. Big FAIL!!

Reducing the bounce rate of tech blogs with Subtext and Lucene.net

In this post I’m going to explain the reason behind my decision to introduce Lucene.net into Subtext to power the internal search engine.

The problem: high bounce rate

It all stared a few week ago, when I noticed that I get lot of visitors from search engines (around 70%) but that they rarely look at more than one page (only 15% read a second page).

I was interested in knowing if this was just a problem of my blog, or a general problem of all tech/dev oriented blogs. So I ran a quick poll over twitter, and I found out that I’m not alone: 66% of the people that responded state that they have an average of less than 2 page views per visit on their developer oriented blog. The remaining 33% state that they have more than 2 pages per visit (actually 24% even more than 3). But this is probably due to different metrics or way of identifying pages per view (I’ve a 7.3 pages per view if I look at the stats provided by stats provided by my provider with AwStats).

In a few words, developer-focused blogs don’t retain the reader for more than one or two pages.

The possible options

I started thinking about ways to reduce the bounce rate, both as a pure SEO exercise but also because this will help readers that come from search engines to find more posts about the keywords they were interested in. Some possible solutions are:

  • Show the best or latest posts of the blog more prominently
  • Show a list of posts similar to the one the visitor is reading
  • If the visitor comes from a search engine, show other posts that match the same keywords

The first option is not something that can be incorporated into a blogging engine as it “only” requires an update in the design of the blog skin. And it won’t give a lot of benefits to the readers because the “best” or “latest” posts might not be about what the reader is looking for.

The solution

So I decided to focus on the other two upgrades, which can be easily introduced into Subtext (or any other blog engine) and that will give a bigger benefit to the reader. And I’m going to develop the following “widgets”:

Why Lucene.net?

Subtext already has a internal search engine that I could have leveraged to power those two widgets, some of you might has why I’m planning to use Lucene.net. The reason is quite simple: Lucene.net is a powerful full-text search engine, with advanced features that allow fast and consistent searches, and that allows the kind of “more like this” search that I need for one of the two widgets. Subtext already has a "Similar Posts” control, but it relies on the categories of posts, so not really that accurate.

And last but not least, Lucene.net will make the internal search engine more accurate, so I’m planning to completely change the search implementation of Subtext.

What’s next

I never used Lucene.net in a real application, so this will also be an interesting journey, that I’ll take with you, my dear readers. I’m planning on writing on this blog who the integration of Lucene.net in Subtext is going, and I’m also going to write a series of posts about how to use Lucene.net. So, stay tuned!!