First we will need to setup the JsonResult controller action.
///
/// Get Models
///
///
///
public JsonResult GetModels(string id)
{
JsonResult result = new JsonResult();
var filteredModels = from model in homeViewModel.Models
where model.MakeID.ToString() == id
select model;
result.Data = filteredModels.ToList();
result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return result;
}
This method now gives us the ability to use the nifty $.getJSON jquery call.
The signature for the call is as follows
jQuery.getJSON( url, [ data ], [ callback(data, textStatus) ] )
Given that we have setup 2 Drop Down Lists, one for Makes and the other for Models, like so.
we can include the following bit of jquery
//Hook onto the MakeID list's onchange event
$("#MakeID").change(function() {
//build the request url
var url = '' + "Home/GetModels";
//fire off the request, passing it the id which is the MakeID's selected item value
$.getJSON(url, { id: $("#MakeID").val() }, function(data) {
//Clear the Model list
$("#ModelID").empty();
//Foreach Model in the list, add a model option from the data returned
$.each(data, function(index, optionData) {
$("#ModelID").append("" + optionData.Description + "");
});
});
}).change();
CascadingDropDownList.zip (365.72 kb)
8e9ecd79-e81d-45a1-bcfc-0f862fa90a2b|0|.0
Never trust user input!
This week at MIX10, Phill Haack had a presentation on what is new with ASP.NET MVC 2.0. The following is a list of the new features in ASP.NET MVC 2.0 from Scott Guthrie’s blog
I have recently been tinkering with an amazing validation engine in jquery from Cedric Dugas. I thought to myself, what an awesome idea it would be to try and minimize the effort of adding the validation engine to the Model Validation inside ASP.NET MVC 2.0.
The first step was to determine where the validation was taking place.
Inside of jquery.validate.js, I found the formatAndAdd function on line number 574. After the error message is constructed, I added the validationEngine.buildPrompt function which is a way for developers to utilize the nice looking prompt that is packaged as part of the plugin.
formatAndAdd: function(element, rule) {
var message = this.defaultMessage(element, rule.method),
theregex = /\$?\{(\d+)\}/g;
if (typeof message == "function") {
message = message.call(this, rule.parameters, element);
} else if (theregex.test(message)) {
message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);
}
$.validationEngine.buildPrompt(element, message, "error");
this.errorList.push({
message: "",
element: element
});
this.errorMap[element.name] = message;
this.submitted[element.name] = message;
},
Step two to determine where the errors are removed, when they have passed the validation rule.
I found an unhighlight function on line 259 of the jquery.validate script. This code doesn’t remove the error, but it does remove the highlighting from the control. I decided to tie into this piece of code by adding the closePrompt method from the validation engine.
unhighlight: function(element, errorClass, validClass) {
$.validationEngine.closePrompt(element);
$(element).removeClass(errorClass).addClass(validClass);
}
The final step is to initialize the validation engine.
on line 50, after the submit button was clicked, we will initialize our validation engine.
if (validator.settings.onsubmit) {
$(validator.currentForm).validationEngine();
Here is the sample code. To utilize this code, all you will need to do is get the latest version of the Validation Engine and replace the jquery.validation.js with this one.
jquery.validate.js (48.89 kb)
ValidationDemo.zip (391.38 kb)
Update : An Update from the Validation Engine guru over at position-absolute now removes the box when you click on it, if it’s in the way.
bef5dfa6-87ae-403f-8410-056152b856d8|2|4.5
It’s difficult to break away from old traditions, but sometimes it pays to think a differently. NHibernate is an awesome example of what I am talking about. It gives a developer the flexibility of concentrating on writing code instead of having to synchronize the database with the data layer/code.
Currently, what I see happening quite often is the following.
- Specification document gets drawn up.
- Database is slapped together by the developer or DB “dude”.
- Developer starts working on the code, only to realize that a column is missing due to either poor planning or requirements changing, the developer spends time having to change/add a column/s and tracking down all the changes in the stored procedure and hopefully he/she has tracked all of them down, otherwise….
I have 2 words, Fluent NHibernate…
How to setup Fluent NHibernate
- Download Fluent NHibernate from http://fluentnhibernate.org/downloads
- Add references to the DLLs
- Create your first Entity
public class Person
{
public virtual int ID { get; private set; }
public virtual string Name { get; set; }
public virtual string Lastname { get; set; }
}
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Schema("dbo");
Table("Person");
Id(x => x.ID);
Map(x => x.Name);
Map(x => x.Lastname);
}
}
- Setup Fluent NHibernate and this is where fluent really shines. No more having to deal with the pain of the XML configuration.
public static class SessionFactory
{
public static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005
.ConnectionString(
c => c.FromConnectionStringWithKey("AthenaConnectionString")))
.Mappings(
m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
private static void BuildSchema(Configuration config)
{
new SchemaUpdate(config).Execute(true, true);
}
}
- How to use Fluent NHibernate in a simple example
var sessionFactory = SessionFactory.CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
Person person = new Person { Name = "Pieter", Lastname = "Germishuys" };
session.SaveOrUpdate(person);
transaction.Commit();
}
}
3JDQDM2DSFR8
15a366ee-39e4-46da-877b-2f43c74fde1b|0|.0
Isn’t symmetry nice? I always have some OCD when it comes to diagrams. So, it’s not surprise when you see this screenshot of the Linq2Sql Context
Along with this, now we can go ahead and create Athena.DAL which contains the Linq2Sql context.
The solution isn’t that far long, so I won’t put up any code yet.
From this fantastic post on implementing the Repository pattern using Linq2SQL, we quickly put together some code that resembles the following
The Repository Interface
namespace Athena.DAL
{
/// <summary>
/// Repository Contract
/// </summary>
public interface IRepository<TRow, TEntity>
where TRow : class
{
#region Find
IList<TEntity> Find(Expression<Func<TRow, bool>> exp);
TEntity FindSingle(Expression<Func<TRow, bool>> exp);
#endregion
#region Save
void Save(TEntity entity);
#endregion
#region Delete
void Delete(TEntity entity);
#endregion
}
}
Our Entry Model, which will describe an Entry fully
namespace Athena.DAL
{
/// <summary>
/// Entry Model
/// </summary>
public class EntryModel
{
public Entry Entry { get; set; }
public List<Tag> Tags { get; set; }
public List<Category> Categories { get; set; }
}
}
and now for our not yet implemented EntryRepository
namespace Athena.DAL
{
/// <summary>
/// Entry Repository
/// </summary>
public class EntryRepository : IRepository<Entry, EntryModel>
{
#region Find
/// <summary>
/// Find
/// </summary>
/// <param name="exp"></param>
/// <returns></returns>
public IList<EntryModel> Find(System.Linq.Expressions.Expression<Func<Entry, bool>> exp)
{
throw new NotImplementedException();
}
/// <summary>
/// Find Single
/// </summary>
/// <param name="exp"></param>
/// <returns></returns>
public EntryModel FindSingle(System.Linq.Expressions.Expression<Func<Entry, bool>> exp)
{
throw new NotImplementedException();
}
#endregion
#region Save
/// <summary>
/// Save
/// </summary>
/// <param name="entity"></param>
public void Save(EntryModel entityModel)
{
throw new NotImplementedException();
}
#endregion
#region Delete
/// <summary>
/// Delete
/// </summary>
/// <param name="entity"></param>
public void Delete(EntryModel entityModel)
{
throw new NotImplementedException();
}
#endregion
}
}
88900210-1026-48dc-8bb3-13181c890c4a|0|.0
So, here is a quick database design of Athena, the blogging engine that I am building as a pet project. Also, my girlfriend recently asked me if I wouldn’t code something for her, so there is some motivation behind it, other than the geek inside of me.
Next, we need to create a new ASP.NET MVC 2.0 Project and start working on the model.
b8e1ac28-ae5f-4c11-beaa-2719657b6ee1|0|.0
This framework is not at all supposed to challenge or replace a blog engine but to merely be an effort from myself to showcase some of the fantastic and cool technologies out there.
I chose Athena because she is the Greek god of wisdom!

I have already blogged about some of technologies that we are going to use, so tonight, we are just going to quickly put the framework together and then start playing.
06e507f6-b20f-491c-9279-4ba4836df3a4|0|.0
Caching considerations
Donut hole caching from Phill Haack!
The Repository Pattern
This thread on StackOverflow
The Output cache is a clear winner for fast and effective caching, but like Mr. Haack has mentioned, only use it when it’s the right tool for the job. The Output Cache can give a great bit of flexibility with regards to where the output is stored.
The current locations for the Output Cache are the following
from http://support.microsoft.com/kb/323290
- Any - This stores the output cache in the client's browser, on the proxy server (or any other server) that participates in the request, or on the server where the request is processed. By default, Any is selected.
- Client - This stores output cache in the client's browser.
- Downstream - This stores the output cache in any cache-capable devices (other than the origin server) that participate in the request.
- Server - This stores the output cache on the Web server.
- None - This turns off the output cache.
6dffd84f-aec0-4146-b574-b47ad3941735|1|4.0
Models
I currently have about 10 tables which are all sitting inside of a Linq2SQL dbml, I then have a Context class that managed the Linq2SQL database context.
For instance, let’s say I want to get entries, the Context class will make sure that the Linq2Sql context is up and retrieve all the entries
The ViewModels
Every View has a “ViewModel” associated with it. Let me give you an example.
For a blog, where you would like to view an Entry, the Entry might contain a title, content, tags and some comments.
The View Model for the View Entry (View) would look something like this
public class EntryViewModel
{
public Entry Entry { get; set; }
public List<Comment> Comments { get; set; }
public List<Tag> Tags { get; set; }
}
The Controllers
They perform pretty mondain tasks, such as begging the ViewModel for some data. i.e. I want to view entry "”Hello World”, go fetch the data for me. Which the ViewModel in turn requests from the Model.
The Views
They are pretty dumb alright, all they do is take the ViewModel they are given and display it the nicest way they can.
4db437f3-fcf5-4e81-bf23-c9a23f46e35c|0|.0
The technologies that I am using include the following
Data Layer
Linq2SQL
Logging
Log4NET
Client Technologies
ASP.NET MVC 2.0
JQuery
ValidationEngine (Because validation is a mess :))
Mocking Framework
MOQ
7d526198-a244-4cdd-842b-3dfdf44e0647|0|.0