Archive

Archive for the ‘ASP.NET MVC’ Category

JQuery Template

March 3, 2011 2 comments

One of the reasons I started blogging was to document my project and learning experiences while working on complex problems. Right from the beginning of my career I was good in writing quick prototypes and small end-to-end proof of concepts, but what I was really not good at was the ability to remember it after sometime. So that way my blog is becoming my software repository and I am glad that it helping other guys who are about to use a particular technology or design principle.

In today’s post I am going to talk about JQuery Template although I did mention briefly about it in my previous post a 8 months ago. But this time I am going to show a full end to end solution and some tips.

The powerful thing about JQuery template is that the template runs in the browser (i.e. on client side) and hence you are taking the client CPU in order to process the template, it’s also better than using string concatenation server side and building HTML string.

So I am going to show a simple list of contact i.e Full name,Age,Phone and some sort of description and our contact class looks like this.

Contact.cs

public class Contact
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Phone { get; set; }
    public string Description { get; set; }

    public Contact(string name,int age,string phone,string description)
    {
        Name = name;
        Age = age;
        Phone = phone;
        Description = description;
    }
}

and the controller

ContactController.cs

public class ContactController : Controller
{
    public JsonResult GetContacts()
    {
        List<Contact> contacts = new List<Contact>()
        {
            new Contact("Joe Blogg",29,"02-6290-0011","A good fellow"),
            new Contact("James Weathers",39,"02-6290-0012","An intelligent fellow"),
            new Contact("John Smith",49,"02-6290-0013","A very wise fellow")
        }; // Just for the demo

        return Json(contacts, JsonRequestBehavior.AllowGet);
    }
}

The reason for returning a JSONResultSet is to show you guys how we can use JQuery to invoke the controller action. Lets see how the view looks like.

Index.aspx

<%@ Page Title="" Language="C#" 
         MasterPageFile="~/Views/Shared/Site.Master" 
         Inherits="System.Web.Mvc.ViewPage<JQueryTemplate.Models.Contact>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Contact
</asp:Content
>
<
asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Contact</h2>
    <script type="text/javascript">

        var templateName = "contactTemplate";
        var resultList = "#contactList";

        $(document).ready(function () {
            $("#jq-getData").click(function () {
                showContacts();
            });
        });

        function showContacts() {
            $.getJSON("/Contact/GetContacts", function (data) {
                var markup = getMarkup();
                clearResultList();
                loadTemplate(templateName, markup);
                applyTemplate(data);
            });
        };

        function getMarkup() {
            var markup = "<tr><td colspan=’2′ title=’${Description}’>${Name}</td><td>Age: ${Age}</td><td>Phone: ${Phone}</td></tr>";
            return markup;
        };

        function clearResultList() {
            $(resultList).empty();
        };

        function loadTemplate(templateName, markup) {
            $.template(templateName, markup);
        };

        function applyTemplate(data) {
            $.tmpl(templateName, data).appendTo(resultList);
        };

    </script>

    <input type="button" id="jq-getData" value="Click" />
    <table><tbody id="contactList"></tbody></table
>
</
asp:Content
>

Okay that looks bit lengthy code and I will try to break it down, I will start with the main function showContacts as it is main method which orchestrate other methods.

1. Get Json data for contacts by invoking the GetContacts action on the controller.

2. Get the markup (html template).

3. Clear the Dom element which will hold the output before any processing.

4. Load the template with the template name and assign the markup to it.

5. Apply the template.

As far as writing the template is concern it’s pure html tags and mark each place holders with the “${attribute}” pattern. The important thing is that the attributes in the template placeholder has to match the property of attribute of your JSON object.Lets run the application and see how it renders on the browser.

Result output

Nothing special as you can see the JSON object has the same attribute as it was in the template markup and the template engine was able to map it and process the html. Lets take a look into the caching headers send by the web server when we requested this JSON object.

Result output

As you can see “Last modified” and “Last fetched” are showing the current time but the “Expiry” header is showing a back date of “1970″, this means that every time the page is refreshed or loaded it will request the JSON over and over again and it can impact on your website performance and scalability. Lets fix it by providing some caching into this request by adding and Output Cache directive to the GetContacts action.

[OutputCache(Duration=60,VaryByParam="")]
public JsonResult GetContacts()
{
    List<Contact> contacts = new List<Contact>()
    {
        new Contact("Joe Blogg",29,"02-6290-0011","A good fellow"),
        new Contact("James Weathers",39,"02-6290-0012","An intelligent fellow"),
        new Contact("John Smith",49,"02-6290-0013","A very wise fellow")
    };

    return Json(contacts, JsonRequestBehavior.AllowGet);
}

After this build the solution and request the page again and you will see the expiry headers are added to the response and now the page will be cached on the browser for a minute.

Result output

That’s it for today and I hope you guys will find this end-to-end JQuery Template solution useful for your projects.BTW the Jquery template is available from Microsoft CDN site at http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js.

Automapper

November 2, 2010 3 comments

Recently a friend of mine was talking to me about his interesting project and in the conversation I mentioned him to use Automapper. As he was not aware of it but when I started explaining him he really got intrigued by it. I provided him the link and thought about blogging about it.

As you have guess it, it’s mainly a very smart mapping tool and will do all your left right hand code mapping. Whether it’s a MVC project where you do a lot of mapping between View-Model to DTO’s or whether you are working in an integration, this is something you can’t miss. You can download the assembly from codeplex at http://automapper.codeplex.com/releases/view/44802

Lets see some examples. Lets say i have two classes PersonDisplayVm & PersonDto and the dto instance is called item and the Vm instance is called model. So inorder to map the two objects so that we can copy value from dto to model we create a map between the classes and use the Map function to map it like this.

  Mapper.CreateMap<PersonDto, PersonDisplayVm>();
  Mapper.Map(item, model);

and this is how my two classes look like

public class PersonDisplayVm
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int? Age { get; set; }
    public DateTime CreatedDateTime { get; set; }
}

public class PersonDto : IPersonDto
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int? Age { get; set; }
    public DateTime CreatedDateTime { get; set; }
}

As you can see it already saved a lot of lines of code where we have to painstakingly assigning  value of one attribute in the left hand side to the corresponding value in the right hand side.

Following TDD and our good habit of writing test lets write a quick test.

[TestFixture]
public class When_testing_person_mapping
{
public PersonDto GetPersonDto()
{
     return new PersonDto
                {
                    Id = 1,
                    FirstName = "Joe",
                    LastName = "Blogg",
                    Age = 45,
                    CreatedDateTime = DateTime.Now
                };
}

[Test]
public void Should_be_able_to_map_dto_to_vm()
{
     var dto = GetPersonDto();
     var vm = new PersonDisplayVm();
     Mapper.CreateMap<PersonDto, PersonDisplayVm>();
     Mapper.Map(dto, vm);
     Assert.IsTrue(dto.Id == vm.Id);
}

Now lets say if for some reason in my display view-model I have the created datetime as string if we try to do a automapping from view-model to dto then we get an exception like

Exception of type ‘AutoMapper.AutoMapperMappingException’ was thrown.

as the string datetime when intialize with DateTime.Now add AM PM string into the string field and automapper can’t map it directly.In order to fix this problem you have to create a custom type convertor like this

public class DateTimeTypeConverter : ITypeConverter<string, DateTime>
{
    public DateTime Convert(ResolutionContext context)
    {
        return System.Convert.ToDateTime(context.SourceValue);
    }
}

And add the custom type converter before our mapping happens like this

[Test]
public void Should_be_able_to_map_dto_to_vm()
{
    var dto = GetPersonDto();
    var vm = new PersonDisplayVm();
    Mapper.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());
    Mapper.CreateMap<PersonDto, PersonDisplayVm>();
    Mapper.Map(dto, vm);
    Assert.IsTrue(dto.Id == vm.Id);
}

And you will see our test this time passes with no exceptions.

Now lets say you have another system or some legacy code where the Person class returned has a PersonId field instead of Id and it would be real waste to write another class which looks like the legacy class and write the whole mapping yourself.

This is where some of extensibility point of this mapper comes into play so lets say your legacy class or any other class looks like this.

public class PersonLegacyDto
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int? Age { get; set; }
    public DateTime CreatedDateTime { get; set; }
}

to map the PersonId field to Id field in PersonDto class you can simple specify it like this.

[Test]
public void Should_be_able_to_map_legacy_to_dto()
{
    var dto = GetPersonDto();
    var personLegacy = GetLegacyPerson();
    Mapper.CreateMap<PersonLegacyDto, PersonDto>()
        .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.PersonId))
        ;

    Mapper.Map(personLegacy, dto);
}

and you will see it does rest of the stuff, the .ForMember is an fluent interface so you can chain them for multiple property mapping.I use it quite often as it saves tones of writing left hand right hand code and saves a lot of time and energy. Hope you will find it handy to use and although I am using it in MVC project but can be used in any service/data layer project as well.

HTML Atrributes in MVC 2

October 22, 2010 Leave a comment

Recently I was working with a very interesting form problem and MVC 2, anyway I manage to solve the problem and wanted to use jQuery validation plugin. I knew i had use the htmlattributes property to inject the attributes and this is how it is done.

 

<div class="editor-field">

    <%: Html.TextBoxFor(model => model.Date, new {size = 25}) %>

    <%: Html.ValidationMessageFor(model => model.Date)%>

</div>

 

So here we are saying to the MVC View engine is that when the textbox for the Date field is generated add size as an html attribute with a value of 25,and this is how the output looks in Firebug.

So far so good and now I wanted to use JQuery Validation plugin to validate the date textbox before I submit the form. This is how JQuery validation plugin does a automatic validation of a form.

This is direct code from the Jquery validation plugin page which is at http://docs.jquery.com/Plugins/validation

However when i tried using the class reserved as a htmlattribute I got a clueless runtime error as “CS1513: } expected” and after some mucking around I came to know that you have to use @class instead of class . So when i change my code to this ..

<div class="editor-field">

    <%: Html.TextBoxFor(model => model.Date, new {@class = "required"}) %>

    <%: Html.ValidationMessageFor(model => model.Date)%>

</div>

and as you can see we got what we wanted:)

Mocking Routes

August 18, 2010 1 comment

I have a done a couple of post on how good TDD is and the use of Moq framework and today I am sharing some code to put all these ideas into practice with a real life project.

I have been working in ASP.NET MVC for sometime and this is one area where I first started using Moq and TDD i.e. testing ASP.NET MVC routes. This unit test project is part of the SparkViewEngine post i did some time ago and goes on to show good the MVC architecture is.

The first and foremost thing is to follow the triple “A” principle for writing unit test i.e.

  • Arrange
  • Act
  • Assert

Lets write some code to Mock the HttpContextBase in order to simulate an Http web request and then we are going to test our routes to verify that it maps to our controllers properly.

Mocking the HttpContextBase

As part of the “Arrange” we will create a RouteCollection object and pass it to RegisterRoutes method of the application class. This is the class which inherits from HttpApplication class and gets created in your Global.asax.cs file when you create a new MVC application.

Testing

In the next test we will test that our routes for a detail view. This is where the whole principle of “Separation of Concerns” really shines, we are able to test our routes with hosting on web server, without creating any web page or server pages etc.

Testing Person details

If you notice carefully you can see how I have named these test and have a lot of resemblence with Behaviour Driven Development (BDD) as I am a huge fan of BDD too.

Test View

If your arrange your test view as shown above you will see the highlighted line is really good in terms of readability. Just follow the pattern like

     For {Namespace} when {Class Name} the result expected is {Test Name}

You will see it reads like “For SparkViewEngineTest when TestingRoutes the result expected is This_goes_to_Person_Index_action” .

The whole sentence makes a lot of sense and is quite helpful when working on large projects with lots of unit test. (Another nice pattern to follow for your projects)

And when we run our unit tests we can verify our results.

ASP.NET MVC 3 Preview 1 released

I am excited to see that the ASP.NET MVC 3 Preview 1 has been released and you can get it from microsoft download website.

The features I am interested are:-

  • Razor View Engine and support for multiple view engines
  • Service Location and Dependency Injection Support

And here is this cool video of scott hanselman and Phil haack talking about MVC 3 Preview 1.

Categories: ASP.NET MVC Tags:

Sydney WebCamp Wrap Up

June 9, 2010 2 comments

A nice wrap of the Sydney WebCamp by Catherine Eibner. It was good to hear that Scott Hanselman and James Senior both acknowledged that Sydney Webcamp was the best.

It was a huge success in its opening year and i hope it becomes even bigger in coming years :)

Race Day Commander – Project Setup

I have been very busy with lot of stuff and haven’t been able to focus on the “Race Day commander” project, in fact the day we  put the prototype in codeplex we haven’t had chance to even look at it.

It was good that one of my mates downloaded the project and reported that he had some problems in running the project.I knew what the problem could be and thought I will write a few instruction on how to setup the project.

So here is how you can make at least the project up and running while we work on adding real bits to make it a real-life application.

  1. Download the database file(.bak) and the VS solutions file from here.
  2. Restore it in your SQLExpress database and the name the database as RDC.
  3. Change the connection string in both web.config files i.e. RDC.Admin & RDC.Web project, right now it says BART_PC\SQLExpress and change it to .\SQLExpress.
  4. Run the project and browse to http://localhost:22676/Event/Index/1 as the default routing takes you the home index page and we haven’t fixed it yet.
  5. Open a new instance of your browser and browse to http://localhost:32124/Comments/List.aspx and add comments. This is the dynamic data page which we tried to demonstrate during the demo.
  6. Enter a few sentences in the comment field and enter todays date time in format dd/mm/yy hh:mn:ss so that the comments get added as the latest comment.
  7. Flip back to the main application and you will see the comment appearing automatically.

In upcoming days i will start blogging into “deep dive” kind of stuff, meanwhile any feedback or comment is most welcome.

Race Day Commander
Race Day Commander with comments

Telerik Extensions for ASP.NET MVC

I know 5 minutes is too short to explain the architecture design & components of an app, even if the application was build in 6 hours. One of things which we showed during the web camp presentation was the Telerik Extensions for ASP.NET MVC.

I know a lot of people were confused by this  super-ninja style discussion  we had with Scott Hansleman . So i thought i would put some references about this extension and how we can use it for web assets management. Here is the link to learn all about it. http://www.telerik.com/help/aspnet-mvc/introduction.html .

Telerik Extensions for ASP.NET MVC helps you manage your web assets easily by providing the following features:

Hope it will give you the bigger picture of the whole extensibility of ASP.NET MVC as well and help you write highly responsive website.

Also worth mentioning is to plan using the existing CDN or building your own.

Follow

Get every new post delivered to your Inbox.