Null !== Steve

Steve Gentile's Tech Blog – Thoughts and Musings

Archive for the category “ASP.NET MVC”

KnockoutJS & ASP.NET Mvc Partial View Loading

Recently I’ve needed to dynamically load ‘partial views’ that are bound to KnockoutJS view models.  The application is a single page app approach, composite application where I’m loading a particular view.

Retrieving the ‘partialView’ is rather simple with ASP.NET Mvc:

image

This is rather straightforward.   I make the call to retrieve the template with a jQuery ajax call:

image

I create my viewmodel, and my viewmodel has a property with the partialViewName defined – ie. self.partialViewName = “_SomePartialView”;

This works very well so far – I have some caching of the html partial, although I might remove this and just takes a more server side ‘get’ ‘varybyparam’ caching on the controller action.

Previously I had an approach like this:

<div data-bind=”with: myViewModel”>
@Html.Partial(“_SomePartialView”)
</div>

Which I still believe works good for one or two scenarios – but the number of viewmodel objects (I have 20+ views here getting loaded) let me change my approach to more of a ‘load on demand’.  I’m pretty happy with this!

Update: one of my concerns that I meant to research and apply here is the impact of loading vm’s to the same dom node with applyBinding and memory leaks.

A good response to this on stack overflow: http://stackoverflow.com/questions/10048485/how-to-clear-remove-observable-bindings-in-knockout-js/10049722#10049722

So what I do for this is use the ko.cleanNode prior to re-applying this binding to the same node:

image

Asp.net mvc ideas for version 4 – the ‘Model’

Phil Haack from the asp.net mvc team mentioned features for asp.net mvc 4.0 on twitter today, and I followed up saying we need some command line ‘scaffolding’ capabilities, ie. Rails 3 style via a ‘nuget’ like interface in Visual Studio.

Scott Hanselman tweeted back about his blog post from PDC: http://www.hanselman.com/blog/CategoryView.aspx?category=PDC in which he touches on a mvc scaffolding concept.

That said, I wanted to add to that and express some more details after working a bit with Rails 3.

First, a problem I see, which is ironic, since Microsoft has always been fairly ‘opinionated’ on how things should be built, that in this case, asp.net mvc is – in my opinion – not very opinionated when it comes to critical items like the model and dependency injection, etc…  They have provided hooks, but the beauty, imo, of Rails is that we want more opinionated and a straightforward approach, with the ability to plug your own.

What do I mean?  In Rails 3, they have the ‘Gemfile’ concept – where you can customize the defaults of what you get with Rails 3 – everything from what type of ORM, to what javascript library (ie jQuery instead of prototype), etc…

That said, I’m actually suggesting, to go along with the scaffolding, that we get some ‘opinionated’ options here in asp.net mvc 4 – and certainly if the community wants to come in an define their own they can, but we want to concentrate on building the apps, not be tied all up into the infrastructure – ie. how to set the controller factory, etc..

So, in the example from Scott’s blog – which is a start – there is a ‘DbContext’ being created and a model being handcrafted.  This is exactly the weak spot in asp.net mvc – we have 4 (or more) view engines, a brand new one – we have tons of controller- results, metadata attributes, json inputs, etc.. but the model part… is like the red headed stepchild – where is it!!!!???  And that irony to me is we are dealing with a company that invests a ton in database, modelling, ORM’s like linq to sql and EF, P&P data guidance, etc… so where the … is my opinionated model???

So, I think asp.net mvc needs to take that step.

Scaffold-Controller -m Post title:string, body:string

Generate my DbContext, read from my connection string in the web.config – generate my model.  (heck, at this point I’ll even take a partial class Post : Model class and you can stuff all your validation, mapping) attributes somewhere.

Get the idea ?  Throw your Entity Framework in, make it the default – if NHibernate or L2S want their own, provide some sort of ‘Gemfile’ hooks and others can create their own ORM plug-ins – but start with Entity Framework and get the model solid.

Next, the DI pieces.  This should be more automatic.  Gemfile your default, make it Unity, I don’t really care, and guys like Castle, NInject, Spring.NET, they can create the plugins so when you create your app and run your bundle script against the Gemfile, we can at least get some opinionated default DI happening.

So, just a few ideas.  I don’t want to say I was ‘disappointed’ with Razor, as nothing was wrong with it – at the same time, I think the core pieces of what asp.net mvc is to get these critical pieces in vs. just adding yet another new view engine to learn.

I’ve worked on three considerable asp.net mvc apps after a career in asp.net webforms, and asp.net mvc knocks the socks off webforms.  But the pain points were setting up the models, the repository patterns, the DI – and using ‘add new view’ dialogues were painful.  So I would want this scaffolding to create the model, create a context if one doesn’t exist.  My model’s should allow me to then add a query to post:

public partial class Post

[required] //adding validation to the property
public string Title{get;set;}

public List<Post> GetAllPostsTitle(string title){
return Post.Where(c.Title == title).ToList();
}

I don’t really honestly want to be wondering the ‘how’ here – sure, you can give me hooks to it, but let’s get the DbContext out of the picture – this Post class should have all the normal CRUD in the generated partial Post class, and allow the developer to extend it and add the specific queries and metadata.

This is one of the parts of Rails that just shines really bright – why not pull together these infrastructure pieces and let us the developers get back to writing that domain logic we need without being so tied to things like ‘DbContexts’.

One last comment – don’t let the actual full scaffolding be the focus.  Most devs see that as ‘nice to have’  - and might use it on some admin type pages, but typically that is good ‘demo’ code.  The command line needs to be focusing primarily on the model and controller.

In summary, I see a good start from PDC talk by Scott.  It looked very rough.  It needs to be well thought out and the asp.net mvc team should, imo – start to think about adding some opinionated builder capabilities to help the asp.net mvc devs be more productive, less ‘GUI’ based, and build on the VS command line capability we see in nuget.  Concentrate on the ‘M’ part, as the ‘V’ is saturated right now.

There you have it, an opinionated blog post on wanting a more opinionated asp.net mvc framework  :)

Knockout – quick asp.net mvc sample

Steve Sanderson has released knockout  – read more here about what knockout is.

Knockout is a JavaScript library that makes it easier to create rich, desktop-like user interfaces with JavaScript and HTML, using observers to make your UI automatically stay in sync with an underlying data model. It works particularly well with the MVVM pattern, offering declarative bindings somewhat like Silverlight but without the browser plugin.

Well, as a fan of his asp.net mvc book (Pro ASP.NET MVC Framework (mvc1) and just recent release of Pro ASP.NET MVC 2 – and please note – knockout isn’t at all associated or tied to asp.net mvc!) – I was quickly wanting to take his editor sample – which was so elegantly put together – and simple show a way to pass json data from a controller action to his sample.

Here is the sample code.

I’m not going to go too much into knockout – simply because Steve’s post and sample page describe it very well.  I do think this is a good follow up to a post a made regarding jTemplates. 

Enjoy!

ASP.NET MVC – jQuery – Json.. Cascading Dropdown

I’m less interested in the ‘cascading dropdown’ part of this post , as I am in demonstrating how json and jquery can be your friends in the asp.net mvc world.

Let’s start by a description of the ‘problem’:  On populating a page, we need to query for a set of companies and display those to the user.  Upon selection of a company, we need to populate another dropdown of the banks associated to that company.  You can fill in the blanks for ‘companies’with ‘banks’ – basically a one to many.  In my situation, I use lazy loading and do not need to pull all the banks in when the page loads.

First let’s look at the ‘onLoad’ of the page via jQuery:
$(function () {
  $("#companies").change(function () {
    LoadBanks($("#companies").val());
    });
  });

I’ve simplified this from the code to show the essentials.  I’m handling the onChange of the companies drop down list, something like this:
Select Company: <%= Html.DropDownList("companies", new SelectList(Model, "Companyid", "Name"), string.Empty)%>
The Model is my list of ‘Company’ objects.  The value is the id and the text is the name.
From the above javascript, you’ll see that when the dropdown item is selected I will be passing the selected value – which is the id – to the LoadBanks function:

function LoadBanks(companyId) {
 $.ajax({
  type: "POST",
  url: BuildUrl("Company/LoadBanks"),
  data: ({ id: companyId }),
  dataType: "json",
  beforeSend: function () {
$.blockUI({ message: "Retrieving Banks..." });   //this is great plugin - 'blockUI'
},
success: function (positivePayBanks) {
  $("#positivePayBanks").find('option').remove();
  $banks = $("#positivePayBanks");
  $.each(positivePayBanks, function (i, bank) {
  if (i == 0) { $("#BankID").val(bank.BankID); }
   $banks.append('<option value="' + bank.BankID + '">' + bank.BankName + '</option>');
  });
$.unblockUI();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
  $.unblockUI();
  var errMsg = "<P>Error Loading: " + XMLHttpRequest.responseText + "<br/>";
  $("#status").html(errMsg).show("slow");
}
});
}

So, what is going on in this call?

type: "POST"
url: BuildUrl("Company/LoadBanks"),   <-- the BuildUrl is just a helper call - basically this is the REST call to the controller/action
data: ({ id: companyId }),   <-- this is the params being sent to the Action.  I'm passing the selected company id
dataType: "json",   <--  I'm saying that the returning data will be json.

Let’s step out of the javascript/html to just show how easy it is to serialize the list of banks to json in mvc:
This isn’t too exciting but here is the controller action for ‘LoadBanks’:

[HttpPost]    <-- I'm requiring this to be a post here
public ActionResult LoadBanks(string id) <--- this id will pick up the id passed in the ajax call above
{
  var positivePayBanks = _companyService.GetBanksByCompanyId(new Guid(id));
  return Json(positivePayBanks);
}

Pretty boring isn’t it?  The simplicity here is appreciate though as mvc includes a JsonResult that will take the list of banks and generate the json!
Here is the select html:

<select id="positivePayBanks" class="required"></select>

The meat here of the post is how we can take that resulting json data and ‘bind’ it to the bank dropdown:

success: function (positivePayBanks) {   <--- 'positivePayBanks' is the returning json data
  $("#positivePayBanks").find('option').remove();     <--- this clears it each time, as it will continue to just append if I don't first remove it!
  $banks = $("#positivePayBanks");
  $.each(positivePayBanks, function (i, bank) {    <--- the beauty of jQuery here is a nice foreach statement
   if (i == 0) { $("#BankID").val(bank.BankID); }    <-- I'm actually forced to set the id of the selected bank or the form post doesn't catch it.
   $banks.append('<option value="' + bank.BankID + '">' + bank.BankName + '</option>');   <-- append the results to the select
  });
$.unblockUI(); //unblock the UI
}

I left the blockUI in this sample because I want to remind those using ajax, that there is no control over the latency on the network – so rather than leave the user wondering what just happened, this gives a visible indicator.
For those new to Json, the part I like the best here is that jQuery will deserialize the json data into the ajax result:
(success: function (positivePayBanks))
Since this is a list of banks, we can use jQuery to loop through each one and it is represented as a bank object, which allows for the ‘bank.BankID’ and ‘bank.BankName’
Just as a finishing note, it is possible to just return a partialview with a Html.DropdownList , etc..  - however, by using Json , it greatly decreases the transmission over the wire.  Json is a perfect medium for keeping the data minimal, and as you can see it goes hand in hand with frameworks like jQuery.
One piece of this I do not like, is how I needed to then set the selected bankId to a hidden field.  I was able to get the value passed into the form collection on form post naturally.  If anyone has a trick for that- let me know  :)
PS. I’m still looking for a good WordPress application to run on MacBook

ASP.NET MVC with jTemplates – Part I

One of my goals in web development is to continue to look to use json to transmit data vs. using partial views.  Obviously by transmitting json data, the payload is going to be much more efficient.

I’m going to break this out into two parts :

Part I is going to cover the basics to using jTemplate with jQuery within an asp.net mvc environment.

Part II is going to take this concept and apply it to a nice looking jQuery plugin ‘grid control’ called  DataTables

Let’s look at what the final result will be:

image

Let’s address the server side pieces first:

I’m going to create a new Model class ‘Person’:

public class Person
    {
        public string ID { get; set; }
        public string FirstName { get; set; }
        public string Email { get; set; }
    }

Using the default asp.net mvc created project type, I’ll just a hook into the the Home controller to display the table in the index page.  To do this, I’ll need to add another action with some sample data that will be called from the page via ajax:

 

 [HttpPost]
 public JsonResult GetData()
 {
      IList<Person> people = new List<Person>
        {
          new Person {ID = "1", FirstName = "Anne", Email = "anne@domain.com"},
          new Person {ID = "2", FirstName = "Amelie", Email = "amelie@domain.com"},
          new Person {ID = "3", FirstName = "Polly", Email = "polly@domain.com"},
          new Person {ID = "4", FirstName = "Alice", Email = "alice@domain.com"},
          new Person {ID = "5", FirstName = "Martha", Email = "martha@domain.com"}
        };
      return Json(people);
}

The ‘return Json(people)’ will return the list in json format – which you can see in the above Firebug screenshot ‘response’. 

So that is basically it for the server side.

The first step in the views is to add the references to the javascript files.  Since I’m using the site.master I’ll add it there, so that it’s available to other views as well:

image 

(For production, you will want to use the compressed/min files instead)

I also add a new ContentPlaceHolder in the head of the site.master:

<asp:ContentPlaceHolder ID="HeadContent" runat="server" />

This way on the views, I can put any scripts in the head tags as well.

In the Index.aspx page we can finish this functionality:

1. add the scripts to the head of the view:

<asp:Content ID="Content3" ContentPlaceHolderID="HeadContent" runat="server">
    <script type="text/javascript">
        $(document).ready(function () {
        $.ajax({
                type:"POST",
                url: "<%= Url.Action("GetData") %>",
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function(data){
                    $("#jTemplateDemo").setTemplate($("#templateHolder").html());
                    $("#jTemplateDemo").processTemplate(data);
                }
            });
        });
    </script>
</asp:Content>

To review this (we could use a $.getJSON as well) – on the page ready function I’m going to make an ajax call back to the ‘GetData’ action.  This is defined in the ‘url:’ parameter.

In this case there are no parameters being passed so the data is left blank (this is best practice to include “{}” when blank).  It is possible to use a REST url as well with parameters.

We define out contentType (using $.getJSON) would do this automatically.

Lastly, we provide an ‘onSuccess’ function – the ‘data’ will contain the returning Json from our action call.  The next two calls use the jTemplate API to merge the Json data to the templated html, as shown below.

2. add the template to the view:

<script type="text/html" id="templateHolder">
    <table border="1">
    <tr>
        <th>
            First Name
        </th>
        <th>
            Email
        </th>
    </tr>
    {#foreach $T as record} 
        <tr>
            <td>
                {$T.record.FirstName}
            </td>
            <td>
                {$T.record.Email}
            </td>
        </tr>
    {#/for}
</table>
</script>
    
<div id="jTemplateDemo">
</div>

 

One thing to keep in mind is to put this html in the script tag.  Alternatively you could load this template from another file as well.

With this approach we have created a very lightweight approach to passing data from the server to the client – the binding to the template occurs on the client.  If we used partial views, the binding process would occur on the server and transmit the payload with the html, increasing it’s size.  The lightweight json approach is critical especially in our ajax calls

Next post we’ll take this table and convert it into a ‘DataTable’.

I have included this code for your review – download here

Moving to JSON with Client Side Templating for Views

I was Google ‘Buzzing’ today on this and figured I’d post the same here :

My new frontier in asp.net mvc (and hopefully asp.net 4) will be implementing templates and moving to a more rich client ‘json’ experience vs. partials views.

couple of resources:

http://www.west-wind.com/Weblog/posts/509108.aspx

http://weblogs.asp.net/dwahlin/archive/2009/04/17/minimize-code-by-using-jquery-and-data-templates.aspx

http://weblogs.asp.net/dwahlin/archive/2009/05/03/using-jquery-with-client-side-data-binding-templates.aspx

http://starterkit.jsonfx.net/

http://jbst.net/

The Telerik MVC controls use JSON I think behind the scenes.  They have source code – I am interested in evaluating that as well. (I’m using their controls, I mean evaluate as in see the source and how they implement their controls with JSON – in particular their grid control)

What you might appreciate here is that you could, in theory, use this approach as your view for any backend framework.

Also, I know ExtJS has some rich controls, they are all Json related, I think Phil Haack had an article on using mvc with ext.

Basically, today, if you add for example, an item to a ‘grid’, I go behind the scenes, add it – then redisplay the grid.  In these approached, you’d literally just append a row to the grid instead.  Very interesting.   The value is going to be less traffic, as partial views create more traffic.

I see this as well:
ASP.NET AJAX And Client-Side Templates by Dino Esposito:
http://msdn.microsoft.com/en-au/magazine/cc546561.aspx

The HTML Message Pattern by Dino Esposito:
http://msdn.microsoft.com/en-au/magazine/cc699560.aspx

Of course, this all assumes you opt for a rich experience with jSON/jQuery vs. something like Flex or Silverlight  :)

Telerik Extensions 1.0 Released for MVC

Telerik has released their extensions for asp.net MVC .  I’ve used these extensions for a few projects and I really like the way they are setup.  These extensions are a set of html helpers for asp.net mvc 1.0 (and 2.0).

These controls are provided free as open source.  From the release notes:

1. New controls: TreeView, NumericTextBox components, Calendar, DatePicker

2. New Features: Grid grouping, editing and localization

3. Uses JQuery 1.4.2

Be sure to read the release notes to see all the functionality these controls provide.

Learn more (including demos).

Error Logging Modules and Handlers for ASP.NET (Webform/MVC)

I just implemented ‘Elmah’ for my ASP.NET MVC project.   I’m using the SQL logging feature (a script comes with the download).  A sample with asp.net webforms comes with the download.

I followed Darrell Mozingo’s blog post here http://darrell.mozingo.net/2009/02/19/elmah-with-aspnet-mvc/ for setting it up with asp.net mvc.

Additionally I used Dan Swatik’s excellent post on integrating Elmah  using the controller/action  ‘HandleError’ attribute to customize the HandleError attribute (see ‘Action Filtering in Mvc Applications’)

ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment.

Once ELMAH has been dropped into a running web application and configured appropriately, you get the following facilities without changing a single line of your code:

  • Logging of nearly all unhandled exceptions.
  • A web page to remotely view the entire log of recoded exceptions.
  • A web page to remotely view the full details of any one logged exception.
  • In many cases, you can review the original yellow screen of death that ASP.NET generated for a given exception, even with customErrors mode turned off.
  • An e-mail notification of each error at the time it occurs.
  • An RSS feed of the last 15 errors from the log.

Check out the Elmah Wiki writeup by Simone Busoli for a good overview of the features.

Basically I signal all my errors (using a custom Exception object) to Elmah to help assist in an easy way to write errors to SQL, send emails out, and provide a rss feed of the errors.   (I am still using Log4Net, but might just convert everything to Elmah)

This is a ‘must have’ for an asp.net application.

ASP.NET xVal Library with DataAnnotations

Recently I setup a new asp.net mvc application.  After reading Steve Sanderson’s new book – in which he refers to his xVal library, I figured I’d take a look at it.

The main features of the xVal library is it’s ability to apply validation that executes on the server side, as well as the ability to apply client side validation using the same technique.  This is quite powerful.

On the client side, you can use the native asp.net MS library, or jQuery. 

On the server side, there are also options available: DataAnnotations, Castle Validators, or even further, you can write your own IRulesProvider and attach rules programmatically.

I won’t go into ‘how’ to use the library, as Steve has given a great walk through here: xVal – a validation framework for ASP.NET MVC

The second part is the DataAnnotations – which I was glad to have investigated some of Silverlight 3 to understand the concept.  As mentioned in this post by Brad Wilson (DataAnnotations and ASP.NET MVC), “in .NET 3.5 SP 1, the ASP.NET team introduced a new assembly named System.ComponentModel.DataAnnotations…”

I think the real value here is this ‘buddy class’ concept that lets you use validation attributes on code generated classes, ie. Linq to SQL/Entity Framework.  Basically you can add attribute metadata to the generated classes in partial classes.  An example of this can be found here, Integrating xVal Validation with Linq-to-Sql

This is very powerful, in particular how the xVal library gives a developer several options to help apply validation to the model classes.

Great stuff  :)

Maarten Balliauw on ASP.NET MVC Best Practices

Maarten Balliauw shares some best practices on ASP.NET MVC

  • Use model binders where possible
  • Be careful when using model binders
  • Never re-invent the wheel
  • Avoid writing decisions in your view
  • Don’t do lazy loading in your ViewData
  • Put your controllers on a diet
  • Compile your views

Thanks Maarten

Post Navigation

Follow

Get every new post delivered to your Inbox.