Now you can read some post in French!

Thanks to Michel for translating some posts of this blog, here are the links to the french version of ASP.NET and NHibernate articles.

Have fun!

.Net from Japan !!

This is my third week on Japan, and I have a lot of new .Net stuff for the blog, including a set of free tools that work great with your .Net projects: Cruise Control .Net, NAnt, NUnit, PartCover .NET, BugTracker .NET and SVN.

Currently I have this environment up and running for a project I’m working here on Japan (so, this is real). I hope this weekend I will have a chance to write a few posts about how to set up this tools and some examples.

From the WPF side I´m about to start re-building my old ImageDesk application that I wrote long time ago (with the first version of Blend).

 

These are some pictures I took in Japan:

japon dia 2 006 japon dia 2 024

Japon INES 011 hattori hanzo 004

ASP.NET MVC 101 Sheet

ASP.NTE MVC 101 SheetThis sheet contains some snippets and information about ASP.NET MVC 1.0, I compiled most of this information from the ASP.NET MVC official site and from the free chapter of ASP.NET MVC 1.0 eBook:

- ActionResults

- Custom Routes

- Action Filters

- Posting Data

- AJAX

- HTML Helpers

 

As someone who is sarting with ASP.NET MVC, I have found this sheet to be the a good reference to keep it in my desk.

I hope this guide helps you as much as it is helping me!

Download the sheet from here.

ASP.NET MVC and NUnit

This article will show you how to set up an ASP.NET MVC test project using NUnit. As starting project I will use the NHibernate101 project which manages Posts and Categories, we built this project in a previous post .

Before anything, donwnload and install NUnit, for this tutorial we will write tests for the Categories controller’s actions: Index, Create, Edit and Detail.

This is the code of our Categories controller:

   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Web;

   5: using System.Web.Mvc;

   6: using System.Web.Mvc.Ajax;

   7: using Core.Domain.Model;

   8: using Core;

   9: using Core.Domain.Repositories;

  10:  

  11: namespace NHibernate101.Controllers

  12: {

  13:     public class CategoriesController : Controller

  14:     {

  15:  

  16:         public ActionResult Index()

  17:         {

  18:             IRepository<Category> repo = new CategoryRepository();

  19:             return View(repo.GetAll());

  20:         }

  21:  

  22:         public ActionResult Details(Guid id)

  23:         {

  24:             IRepository<Category> repo = new CategoryRepository();

  25:             return View(repo.GetById(id));

  26:         }

  27:  

  28:         public ActionResult Edit(Guid id)

  29:         {

  30:             IRepository<Category> repo = new CategoryRepository();

  31:             return View(repo.GetById(id));

  32:         }

  33:  

  34:         [AcceptVerbs(HttpVerbs.Post)]

  35:         public ActionResult Edit(Guid id, FormCollection formCollection)

  36:         {

  37:             string name = formCollection.Get("Name");

  38:             Category category = new Category() { Id = id, Name = name };

  39:  

  40:             IRepository<Category> repo = new CategoryRepository();

  41:             repo.Update(category);

  42:  

  43:             return RedirectToAction("Index");

  44:         }

  45:  

  46:         public ActionResult Create()

  47:         {

  48:             return View();

  49:         }

  50:  

  51:         [AcceptVerbs(HttpVerbs.Post)]

  52:         public ActionResult Create(FormCollection formCollection)

  53:         {

  54:             string name = formCollection.Get("Name");

  55:             Category category = new Category() { Name = name };

  56:  

  57:             IRepository<Category> repo = new CategoryRepository();

  58:             repo.Save(category);

  59:  

  60:             return RedirectToAction("Index");

  61:         }

  62:  

  63:         public ActionResult Delete(Guid id)

  64:         {

  65:             IRepository<Category> repo = new CategoryRepository();

  66:             repo.Delete(repo.GetById(id));

  67:             return RedirectToAction("Index");

  68:         }

  69:     }

  70: }

 

Write the Tests

Creating unit tests for this controller involves the following steps:

  1. Create a new project to write the tests, e.g: NHibernate101.Tests.
  2. Add references to nunit.framework and nunit.mocks.
  3. Add a reference to the project you want to test and its dependencies.
  4. Create methods decorated with the Test attribute so NUnit can recognize them.

After writing our tests, we will use the NUnit GUI to load the test project assembly and execute the tests, our test project will look like this:

Test Project

Now lets review one of the test methods: CanEditCategory, in this method we are testing that the controller can modify and update the name of a category:

   1: [Test]

   2:         public void CanEditCategory()

   3:         {

   4:             CategoriesController controller = new CategoriesController();

   5:             var result = controller.Index() as ViewResult;

   6:             var categories = (IList<Category>)result.ViewData.Model;

   7:  

   8:             Assume.That(categories.Count > 0, "At least one category must exists to complete this test.");

   9:             if (categories.Count > 0)

  10:             {

  11:                 result = controller.Details(categories[0].Id) as ViewResult;

  12:                 var category = result.ViewData.Model as Category;

  13:                 Assert.IsNotNull(category);

  14:                 Assert.IsNotNullOrEmpty(category.Name);

  15:                 string oldName = category.Name;

  16:                 

  17:                 FormCollection fc = new FormCollection();

  18:                 fc.Add("Name", "This is a TEST name.");

  19:  

  20:                 var redirectResult = controller.Edit(category.Id, fc) as RedirectToRouteResult;

  21:                 Assert.AreEqual("Index", redirectResult.RouteValues["action"]);

  22:  

  23:                 fc["Name"] = oldName;

  24:                 redirectResult = controller.Edit(category.Id, fc) as RedirectToRouteResult;

  25:                 Assert.AreEqual("Index", redirectResult.RouteValues["action"]);

  26:             }

  27:         }

  • Line #4: First we create an instance of the Categories controller.
  • Lines #5 and #6: The Index method will return a list of all categories, we will pick one category from this list. The list of categories is in the ViewData model.
  • Line #7: NUnit provides us with members to “Assume” things, this example assumes that the categories list is not empty. If during the test, this assumption is false (there are no categories) the result wont be a fail, will be  inconclusive.
  • Line #11: We are fetching the first category.
  • Lines #13 and #14: We check that the category returned by controller is not NULL and the name is not empty.
  • Lines #17 and #18: We are setting the new name of the category.
  • Line #20: We call the Edit method of the controller, the expected result is a redirection to the Index action.
  • Line #21: We check that the controller redirects to the Index action.
  • Lines #23, #24, #25: We restore the original name of the category (and we test that too!).

Our test will fail if any of the Assert statements is false.

 

Run the Tests

Open NUnit GUI and add the NHibernate101.Test assembly to the project, NUnit will display the list of test methods, now press Run to execute the tests:

Tests

Inconclusive results

Hopefully, all the methods will pass the test. Now lets  change the assumption rule of the method so the test will be inconclusive:

   1: [Test]

   2:         public void CanEditCategory()

   3:         {

   4:             CategoriesController controller = new CategoriesController();

   5:             var result = controller.Index() as ViewResult;

   6:             var categories = (IList<Category>)result.ViewData.Model;

   7:  

   8:             Assume.That(categories.Count > 10, "At least one category must exists to complete this test.");

   9:             if (categories.Count > 10)

  10:             {

  11:                 result = controller.Details(categories[0].Id) as ViewResult;

  12:                 var category = result.ViewData.Model as Category;

  13:                 Assert.IsNotNull(category);

  14:                 Assert.IsNotNullOrEmpty(category.Name);

  15:                 string oldName = category.Name;

  16:                 

  17:                 FormCollection fc = new FormCollection();

  18:                 fc.Add("Name", "This is a TEST name.");

  19:  

  20:                 var redirectResult = controller.Edit(category.Id, fc) as RedirectToRouteResult;

  21:                 Assert.AreEqual("Index", redirectResult.RouteValues["action"]);

  22:  

  23:                 fc["Name"] = oldName;

  24:                 redirectResult = controller.Edit(category.Id, fc) as RedirectToRouteResult;

  25:                 Assert.AreEqual("Index", redirectResult.RouteValues["action"]);

  26:             }

  27:         }

Line #8: Now we assume that there should be more than 10 categories.

If we run the test again, the result will be inconclusive:

Inconclusive

Fail the Test

To make it fail we will make a simple change:

   1: [Test]

   2:         public void CanEditCategory()

   3:         {

   4:             CategoriesController controller = new CategoriesController();

   5:             var result = controller.Index() as ViewResult;

   6:             var categories = (IList<Category>)result.ViewData.Model;

   7:  

   8:             Assume.That(categories.Count > 0, "At least one category must exists to complete this test.");

   9:             if (categories.Count > 0)

  10:             {

  11:                 result = controller.Details(categories[0].Id) as ViewResult;

  12:                 var category = result.ViewData.Model as Category;

  13:                 category = null;

  14:                 Assert.IsNotNull(category);

  15:                 Assert.IsNotNullOrEmpty(category.Name);

  16:                 string oldName = category.Name;

  17:                 

  18:                 FormCollection fc = new FormCollection();

  19:                 fc.Add("Name", "This is a TEST name.");

  20:  

  21:                 var redirectResult = controller.Edit(category.Id, fc) as RedirectToRouteResult;

  22:                 Assert.AreEqual("Index", redirectResult.RouteValues["action"]);

  23:  

  24:                 fc["Name"] = oldName;

  25:                 redirectResult = controller.Edit(category.Id, fc) as RedirectToRouteResult;

  26:                 Assert.AreEqual("Index", redirectResult.RouteValues["action"]);

  27:             }

  28:         }

Line #13: We are setting the category to NULL.

Error

 

Conclusion

Unit Testing helps us to improve the quality of our code and we should always keep in mind how are we going to test that piece of code we are writting. Nunit provides an easy and simple way to write and run tests for our code. There is a lot of stuff about Unit Testing thats is not covered in this article, but I hope this will give you a initial idea of how to write unit tests for your ASP.NET MVC projects (or any .Net project).

 

 Download Project Source Code

Using ASP.NET MVC and NHibernate (Part 3 – final)

This is the third and last part of a series of articles about using NHibernate in an ASP.NET MVC application. These are the links of the two previous posts:

In this article we will create our ASP.NET MVC application to manage Posts and Categories. Our project will have the following structure:

image

The CategoriesController will let us Fetch, Create,Update and delete categories from our repository.

The PostController will let us do the equivalent for Posts, for the Post views I’m using a  ViewModel to represent the combination of Posts and Categories.

In our ASP.NET MVC applications we will add references to our Core and Infrastructure projects in order to use our NHibernate persistency components.

We are using strongly-typed views based on our Models an ViewModel so the tool can scaffold our views based on those types.

NewView DetailsCreated

I did little changes to the code (thanks to Unit Testing I detected some bugs in the code), so make sure to download the complete version  of the project.

 

ViewModel

The Posts views needs the Post and Category domain objects to render properly, a common pattern is to introduce a view model that acts as a container for those objects in order to facilitate the render of the View.

For the Posts controller views, I’m not directly using  the Domain Model (Post and Category classes), instead I created a  PostViewModel that contains those domain objects. This way I can simplify handling Posts and related Categories as a “single unit”.

image

 

Conclusion

Configuring NHibernate the first time may require a some effort (a little bit), but it will save you a lot of time while working in the data layer of your application, combined with a framework like ASP.NET MVC you can have a clear separation of concerns that enables you keep your project well organized, easy to understand and create unit tests. I believe the result of this process is an elegant project structure and code and Visual Studio templates for ASP.NET MVC make the job even easier since you can scaffold the Views.

It’s amazing how easy and fast is to create applications with ASP.NET MVC, I’m looking forward for version 2.0 (I’m already playing with the Preview version). It’s an exciting time to learn ASP.NET, MVC and NHibernate.

 

Download complete source code.

Using ASP.NET MVC and NHibernate (Part 2)

This is the second part of a series of articles about using NHibernate in an ASP.NET MVC application, you can read the first part here.

 

Put it on the Bag

We will continue by creating a map file for the Post class, this is a little bit different than the Category map file since now we have to represent a many-to-many relationship between Posts and Categories, we accomplish this by using the BAG element in the map file, this is the code of the Post.hbm.xml file:

IMPORTANT: Set the build action of each map file to “Embedded Resource”, this way NHibernate can find the correct file in the  assembly.

Post.hbm.xml

   1: <?xml version="1.0" encoding="utf-8" ?>

   2: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

   3:                                     namespace="Core.Domain.Model"

   4:                                     assembly="Core">

   5:  

   6:   <class name="Post" table="Posts" dynamic-update="true">

   7:     <cache usage="read-write"/>

   8:     <id name="Id" column="Id" type="Guid">

   9:       <generator class="guid"/>

  10:     </id>

  11:     <property name="Title" length="100"/>

  12:     <property name="Body"/>

  13:     <property name="CreationDate" type="datetime"/>

  14:     <property name="IsPublic" type="bool"/>

  15:  

  16:     <bag name="Categories" table="PostCategory" lazy="false" >

  17:       <key column="idPost" ></key>

  18:       <many-to-many class="Category" column="idCategory" ></many-to-many>

  19:     </bag>

  20:     

  21:   </class>

  22: </hibernate-mapping>

The bag element is in lines 16 to 19, here is an explanation of what are we doing:

  • The name attribute is the name of the property of the Post class wehere we will store the categories collection.
  • The table attribute is the name of the table in the datbase that joins the Posts and Categories tables.
  • The key.column attribtue is the name of the key column for the Posts.
  • The class attribute is the name of the Category object model class.
  • The many-to-many.column is the name of the key column for the Categories.

These are both the class diagram (left)  and the database diagram (right) so you can better understand this map file:

Mapping PostsCategories Model

As you can see above, we DON’T need to create a class for the PostCategory table.

 

Test it

Now we will test our repositories and make sure we can create posts, this is the complete unit test code for this example:

   1: using System;

   2: using System.Text;

   3: using System.Collections.Generic;

   4: using System.Linq;

   5: using Microsoft.VisualStudio.TestTools.UnitTesting;

   6: using Core.Domain.Model;

   7: using Core.Domain.Repositories;

   8: using Core;

   9:  

  10: namespace NHibernate101.Tests

  11: {

  12:     [TestClass]

  13:     public class RepositoriesTest

  14:     {

  15:         IRepository<Category> categoriesRepository;

  16:         IRepository<Post> postsRepository;

  17:         Post testPost;

  18:         Category testCategory1;

  19:         Category testCategory2;

  20:  

  21:         public RepositoriesTest()

  22:         {

  23:         }

  24:  

  25:         private TestContext testContextInstance;

  26:  

  27:         public TestContext TestContext

  28:         {

  29:             get

  30:             {

  31:                 return testContextInstance;

  32:             }

  33:             set

  34:             {

  35:                 testContextInstance = value;

  36:             }

  37:         }

  38:  

  39:  

  40:         [TestInitialize()]

  41:         public void CreateRepositories()

  42:         {

  43:             categoriesRepository = new CategoryRepository();

  44:             postsRepository = new PostRepository();

  45:         }

  46:  

  47:  

  48:         [TestMethod]

  49:         [DeploymentItem("hibernate.cfg.xml")]

  50:         public void CanCreateCategory()

  51:         {

  52:             testCategory1 = new Category() { Name = "ASP.NET" };

  53:             categoriesRepository.Save(testCategory1);

  54:  

  55:         }

  56:  

  57:         [TestMethod]

  58:         [DeploymentItem("hibernate.cfg.xml")]

  59:         public void CanCreatePost()

  60:         {

  61:             testPost = new Post();

  62:             testPost.Title = "ASP.NET MVC and NHibernate";

  63:             testPost.Body = "In this article I’m going to cover how to install and configure NHibernate and use it in a ASP.NET MVC application.";

  64:             testPost.CreationDate = DateTime.Now;

  65:             testPost.IsPublic = true;

  66:  

  67:             testCategory2 = new Category() { Name= "ASP.NET MVC"};

  68:  

  69:             categoriesRepository.Save(testCategory2);

  70:             testPost.Categories.Add(testCategory2);

  71:  

  72:             postsRepository.Save(testPost);

  73:  

  74:         }

  75:     }

  76: }

 

Run the test and if it passes, we should see the new post and category in our database:

PostAndCategory

 

This are the basics about NHibernate, I encourage you to continue reading about NHibernate in the community site. In the next part of this tutorial we will begin building our ASP.NET MVC application for posts and categories!

 

Download source code of PART 2

Using ASP.NET MVC and NHibernate (Part 1)

In this article I’m going to cover how to install and configure NHibernate and use it in a ASP.NET MVC application. This is the first part of a series of articles which demonstrates how to set up NHibernate for a .Net Application.

 

 mvc-logo-landing-page  

+

NHLogoSmall

 

What is NHibernate?

NHibernate is an Object-Relational Mapper (ORM) for .Net which allows object-oriented models to be mapped to a relational database. As you will see in this article, NHibernate will takes care of most of the tasks related to the persistent layer. You can learn more about NHibernate from the NHibernate Community Site.

You can download the latest version of NHibernate from SourceForge. The code examples of this article are based on NHibernate 2.1.1 (Which is the most current version at the moment of writting this post).

 

Install NHibernate

Download and unzip the NHibernate in your computer. Thats it, NHibernate installed.

 

Create the ASP.NET MVC project.

Create a new ASP.NET MVC application and make sure to create a test project.

Add two new Class Library Projects to your solution: Infrastructure and Core (to we can keep everything well organized).

In the Core project, add a reference to the NHibernate assembly.+

 

The Database

For this example we are going to create a model of Posts and Categories, this is a very simple model that will help us to understand how NHibernate works: one blog post can be in one or more categories, and one category can hold zero or more than zero posts:

PostsCategories Model

We will use SQL Server 2008 Express Edition to create our database, another option is to create our models in Visual Studio and command NHibernate to create the database for us, but for this case we will manually create the database.

 

Creating the Model

The next step is to create our Model which is an object-oriented representation of our database, we will use the Class Designer of Visual Studio to create it:

PostsCategories Model

 

Repositories

A repository allows us to create, select, update and delete our objects, a repository is independed of the database. For this tutorial we need to create two repositories: PostRepository and CategoryRepository. Both repositories will implement the following interface:

IRepository.cs

   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Text;

   5:  

   6: namespace Core

   7: {

   8:     public interface IRepository<T>

   9:     {

  10:         void Save(T entity);

  11:         void Update(T entity);

  12:         void Delete(Guid id);

  13:         T GetById(Guid id);

  14:         T GetAll();

  15:     }

  16: }

To create our repositories we first need a helper class to create a NHibernate session to our database:

NHibernateHelper.cs

   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Text;

   5: using NHibernate.Cfg;

   6: using NHibernate;

   7:  

   8: namespace Core.Domain.Repositories

   9: {

  10:     public class NHibernateHelper

  11:     {

  12:         private static ISessionFactory _sessionFactory;

  13:  

  14:         private static ISessionFactory SessionFactory

  15:         {

  16:             get

  17:             {

  18:                 if (_sessionFactory == null)

  19:                 {

  20:                     var configuration = new Configuration();

  21:                     configuration.Configure();

  22:                     _sessionFactory = configuration.BuildSessionFactory();

  23:                 }

  24:                 return _sessionFactory;

  25:             }

  26:         }

  27:  

  28:         public static ISession OpenSession()

  29:         {

  30:             return SessionFactory.OpenSession();

  31:         }

  32:     }

  33: }

 

Next, we create the repositories:

PostRepository.cs

   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Text;

   5: using Core.Domain.Model;

   6: using NHibernate;

   7: using NHibernate.Criterion;

   8:  

   9: namespace Core.Domain.Repositories

  10: {

  11:     public class PostRepository: IRepository<Post>

  12:     {

  13:         #region IRepository<Post> Members

  14:  

  15:         void IRepository<Post>.Save(Post entity)

  16:         {

  17:             using (ISession session = NHibernateHelper.OpenSession())

  18:             {

  19:                 using (ITransaction transaction = session.BeginTransaction())

  20:                 {

  21:                     session.Save(entity);

  22:                     transaction.Commit();

  23:                 }

  24:             }

  25:         }

  26:  

  27:         void IRepository<Post>.Update(Post entity)

  28:         {

  29:             using (ISession session = NHibernateHelper.OpenSession())

  30:             {

  31:                 using (ITransaction transaction = session.BeginTransaction())

  32:                 {

  33:                     session.Update(entity);

  34:                     transaction.Commit();

  35:                 }

  36:             }

  37:         }

  38:  

  39:         void IRepository<Post>.Delete(Guid id)

  40:         {

  41:             using (ISession session = NHibernateHelper.OpenSession())

  42:             {

  43:                 using (ITransaction transaction = session.BeginTransaction())

  44:                 {

  45:                     session.Delete(id);

  46:                     transaction.Commit();

  47:                 }

  48:             }

  49:         }

  50:  

  51:         Post IRepository<Post>.GetById(Guid id)

  52:         {

  53:             using (ISession session = NHibernateHelper.OpenSession())

  54:                 return session.CreateCriteria<Post>().Add(Restrictions.Eq("Id", id)).UniqueResult<Post>();

  55:         }

  56:  

  57:         Post IRepository<Post>.GetAll()

  58:         {

  59:             throw new NotImplementedException();

  60:         }

  61:  

  62:         #endregion

  63:     }

  64: }

CategoryRepository.cs

   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Text;

   5: using Core.Domain.Model;

   6: using NHibernate;

   7: using NHibernate.Criterion;

   8:  

   9: namespace Core.Domain.Repositories

  10: {

  11:     public class CategoryRepository: IRepository<Category>

  12:     {

  13:         #region IRepository<Category> Members

  14:  

  15:         void IRepository<Category>.Save(Category entity)

  16:         {

  17:             using (ISession session = NHibernateHelper.OpenSession())

  18:             {

  19:                 using (ITransaction transaction = session.BeginTransaction())

  20:                 {

  21:                     session.Save(entity);

  22:                     transaction.Commit();

  23:                 }

  24:             }

  25:         }

  26:  

  27:         void IRepository<Category>.Update(Category entity)

  28:         {

  29:             using (ISession session = NHibernateHelper.OpenSession())

  30:             {

  31:                 using (ITransaction transaction = session.BeginTransaction())

  32:                 {

  33:                     session.Update(entity);

  34:                     transaction.Commit();

  35:                 }

  36:             }

  37:         }

  38:  

  39:         void IRepository<Category>.Delete(Guid id)

  40:         {

  41:             using (ISession session = NHibernateHelper.OpenSession())

  42:             {

  43:                 using (ITransaction transaction = session.BeginTransaction())

  44:                 {

  45:                     session.Delete(id);

  46:                     transaction.Commit();

  47:                 }

  48:             }

  49:         }

  50:  

  51:         Category IRepository<Category>.GetById(Guid id)

  52:         {

  53:             using (ISession session = NHibernateHelper.OpenSession())

  54:                 return session.CreateCriteria<Category>().Add(Restrictions.Eq("Id", id)).UniqueResult<Category>();

  55:         }

  56:  

  57:         Category IRepository<Category>.GetAll()

  58:         {

  59:             throw new NotImplementedException();

  60:         }

  61:  

  62:         #endregion

  63:     }

  64: }

As you can see, is in the repositories where we put the code to call the NHibernate methods, we do it by creating a Session object first.

 

The history so far…

Before continuing, lets review what have we done so far:

  1. We created a Core project with a reference to the NHibernadte.dll assembly.
  2. In the Core project, we created two classes that represent our model: “Post.cs” and “Category.cs”, the post class has collection of categories.
  3. We created two repositories to save, update, delete and select objects of our model.

The Mappings

Now its time to do some work in our Infrastructure project where will map our model to our database, in NHibernate we do this with XML files. There is a naming convention that we should follow for the map files: [ClassName].hbm.xml.

We will create two new files: Category.hbm.xml and Post.hbm.xml. The content of each file maps a class to a table, and a propery to a column, you also specify the data types. For the first part of this tutorial we need to create the Category.hbm.xml file:

   1: <?xml version="1.0" encoding="utf-8" ?>

   2: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

   3:                                     namespace="Core.Domain.Model"

   4:                                     assembly="Core">

   5:  

   6:   <class name="Category" table="Categories" dynamic-update="true">

   7:     <cache usage="read-write"/>

   8:     <id name="Id" column="Id" type="Guid">

   9:       <generator class="guid"/>

  10:     </id>

  11:     <property name="Name" length="100"/>

  12:   </class>

  13: </hibernate-mapping>

IMPORTANT: Set the build action of each map file to “Embedded Resource”, this way NHibernate can find the correct file in the  assembly.

Configure it

We are almost ready, the next step is to set the database connection and some NHibernate parameters. The configuration should be in a “hibernate.cfg.xml” file (Set the build action of this file to “Embbeded Resource”). NHibernate has a special “Lazy-Loading” feature for dynamic proxy systems, and we need to add  the following references to the Infrastructure project to support it:

  • Castle.Core
  • Castle.DynamicProxy2
  • NHibernate.ByteCode.Castle.dll

Then create the following XML configuration file:

hibernate.cfg.xml

   1: <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">

   2:   <session-factory>

   3:     <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>

   4:     <property name="connection.connection_string">server=.\SQLExpress;database=NHibernate101;Integrated Security=true;</property>

   5:     <property name="show_sql">true</property>

   6:     <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>

   7:     <property name="cache.use_query_cache">false</property>

   8:     <property name="adonet.batch_size">100</property>

   9:     <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>

  10:     <mapping assembly="Infrastructure" />

  11:   </session-factory>

  12: </hibernate-configuration>

Line # 9: Hibernate uses a lazy loading feature , you can find out more about NHibernate lazy load here.

 

Test it

Now it is time to test our NHibernate configuration!!, lets add some fields to our “Categories” Table, for this we need to reference to the NHibernate assebmly and copy the hibernate.cfg.xml to the test poject.

Add the following references:

  • Castle.Core
  • Castle.DynamicProxy2
  • Infrastructure
  • NHibernate
  • NHibernate.ByteCode.Castle

And add the following test method:

   1: [TestMethod]

   2:         [DeploymentItem("hibernate.cfg.xml")]

   3:         public void CanCreateCategory()

   4:         {

   5:             IRepository<Category> repo = new CategoryRepository();

   6:             Category category = new Category();

   7:             category.Name = "ASP.NET";

   8:  

   9:             repo.Save(category);

  10:  

  11:         }

 

Run the test project and our CanCreateCategory test method should pass the test (hopefully):

Test

 

Now lets check the database to see the new category just added:

 Database

 

Download source code of PART 1

In the next part of this tutorial we will complete the model and the unit tests, then we will create our ASP.NET MVC application.

Using ASP.NET MVC and Ajax to check names availability.

This article demonstrates how to use ASP.NET MVC Ajax and JQuery to create a MVC User Control that checks the availability of a name. For example you may want to create a URL route that includes project names as parameters and you want to make sure those names are unique. The control will look like this:

KeyValidator01

Key Validator

Using jQuery and ASP.NET MVC Ajax we can call the view’s controller to check the availability of the name:

KeyValidator02

Validating project name.

KeyValidator03

Project name available.

 

KeyValidator04

Project name already in use.

Open Visual Studio 2008 and create a new ASP.NET MVC 1.0 project, now we need to create the KeyValidatorController class inside the Controllers folder:

 

KeyValidatorController.cs

   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Web;

   5: using System.Web.Mvc;

   6: using System.Web.Mvc.Ajax;

   7: using System.Threading;

   8:  

   9: namespace CheckKeyName.Controllers

  10: {

  11:     public class KeyValidatorController : Controller

  12:     {

  13:         //

  14:         // GET: /KeyValidator/Check

  15:  

  16:         public ActionResult Check(string projectName)

  17:         {

  18:             Thread.Sleep(5000);

  19:  

  20:             if (!String.Equals(projectName, "superProject", StringComparison.InvariantCultureIgnoreCase))

  21:                 return Content("Available");

  22:  

  23:             return Content("Already in use.");

  24:         }

  25:     }

  26: }

 

As you can see in line 18, we are using the Thread.Sleep(5000) method to simulate a 5 seconds delay in our application while the information is retrieved.

Line 20 compares the project name with a hardcoded string and in line 23 we return the text result to the view, pretty simple right? (In a real application we would replace lines 20 and 21 by the actual code to access a names catalog and perform the validation). 

In lines 21 and 23 we are using the Content accion result to return a string to the View.

Now lets create the KeyValidator View by adding a new MVC User Control inside the Shared folder of the Views:

KeyValidator06

KeyValidator.ascx

   1: <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

   2:  

   3: <script language="javascript">

   4:  

   5:     function checking() {

   6:         $("#statusMsg").html('');

   7:         $("#checkButton").hide();

   8:     }

   9:  

  10:     function checked() {

  11:         $("#checkButton").show();

  12:  

  13:         if ($("#statusMsg").html() != "Available")

  14:             $("#statusMsg").addClass("error");

  15:         else

  16:             $("#statusMsg").removeClass("error");

  17:     }

  18:  

  19:     function previewUrl(e) {

  20:         $("#statusMsg").html('');

  21:         $("#projectUrl").html(e.value);

  22:  

  23:     }

  24:  

  25: </script>

  26:  

  27: <%using (Ajax.BeginForm("Check", "KeyValidator", new AjaxOptions { 

  28:       LoadingElementId = "working",

  29:       OnBegin = "checking",

  30:       UpdateTargetId = "statusMsg",

  31:       OnSuccess = "checked"

  32:       

  33:   } )) { %>

  34:  

  35:     <%= Html.TextBox("projectName", null, new { onkeyup = "javascript:previewUrl(this);", style = "float:left;" })%>

  36:     <input id="checkButton" type="submit" value="check"/>

  37:     <img id="working" alt="working" src="../../Content/Images/working.gif" style="display:none;" />

  38:     <div id="statusMsg" style="display:inline"></div>

  39:     <div class="clear"></div>

  40:     http://server/project/<div id="projectUrl" style="display:inline"></div>

  41: <% } %>

 

In this View we are using the Ajax.BeginForm helper to create an Ajax form that will post the data to the Check action of the KeyValidator controller. In line 27 we are setting the following Ajax Form properties:

  • LoadingElementId = "working"

    The ID of the Html element that will be displayed while the request is been completed. In this case we are displaying a progress bar. Note the style="display:none;" attribute in line 37 to hide the image, the MVC Ajax helper will automatically display the image when necessary.
  • OnBegin = "checking"

    The name of the JavaScript function that will be called when the user clicks on the Check button, this function clears any status message and hides the Check button.
  • UpdateTargetId = "statusMsg"

    The ID of the Html element that will be filled with the controller text result.
  • OnSuccess = "checked"

    The name of the JavaScript function that will be called after completing the validation process, in this function we check the controller response and set the style of the text.
  • In line 35 we are using another helper to render a TextBox and we show how to hook the onKeyUp java script event with our previewUrl method to  update the preview URL text.

 

Finally lets modify our Home page to add our user control, open the Index view and add the code to render the partial view (Line 12):

 

Index.aspx

   1: <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

   2:  

   3: <asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">

   4:     Home Page

   5: </asp:Content>

   6:  

   7: <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

   8:     <h2><%= Html.Encode(ViewData["Message"]) %></h2>

   9:     <p>

  10:         To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.

  11:     </p>

  12:     <% Html.RenderPartial("KeyValidator"); %>

  13: </asp:Content>

 

If you run your application, enter different project names and see how the URL preview is updated as you type in, when you press the Check button the progress bar will be displayed and a few seconds later the reponse will be presented to the user.

 

Download the source code

Please remain calm

This installation is under construction and will be available soon.