Technical…Practical…Theoretically Interesting

Scenario: We want to create form where I can save information about a person. That person has zero or more phone numbers and zero or more email addresses. The customer would like to edit everything about a person all at once, on a single form. This is a dynamic nested model problem. Suppose our person object looks like this:

Let’s start with the controller. When new is called, we need to create a new person, and we want to prepopulate the collections with two telephone numbers, one email address, and one address. I’m going to add a few methods to my Person class to help me out. I’m using C#’s new optional parameters feature here.

We’re also going to make use of the EditorFor HTML helper. This helper is smart enough to iterate over a collection, returning a collection of input elements for each object in the collection. From this point on, I’ll only work with phone numbers, but the example is the same. In New.cshtml, we’ll call EditorForModel(). This will look at the type of model (Person), then go looking in your EditorTemplates folder for a file named Person.cshtml. (Yes, this works the same with *.ascx and *.vbhtml.)

Inside of Person.cshtml, we’re going to call EditorFor(Expression). Again, this looks at the return type of the expression and looks for a file name that matches the type. In this case, that will be PhoneNumber.cshtml. Person.cshtml would do the exact same thing for email address and address collections. You would also build editor templates for EmailAddress.cshtml and Address.cshtml and place those in your EditorTemplates folder.

If we were to stop there, we now how a completely dynamic form were the numbers of phone numbers, addresses, and email addresses were set in the controller. That’s a great start! Let’s look a little closer at what just got generated.

We have editors for FirstName and LastName properties in Person.cshtml.

We created a container div tag with the ID #phoneNumbers.

We called EditorFor(x => x.PhoneNumbers), and that looped through our phone numbers and created two nested editors.

Those nested editors are really important. Let’s inspect those input fields. See how MVC tells us their collection, uses a zero-based index, and tells us the property of the object.

This is the proper way to post collections back to MVC. We can also inspect the model on the submit. If you’ve done everything correctly so far, you should see POST data that looks like this:

Of course you know where we’re going with this. We want have some sort of user interaction to dynamically scale these values on the screen. This is usually done with links on the page (and then you can get some fancy CSS to make those links look pretty). Right now, forget the pretty.

Removing a Phone Number

As it turns out, the remove button is really easy, but we need to do some work on our model first. We need to add a boolean property called Delete to flag where or not a record has been marked for deletion. We could send DELETE request to the server as soon as the user clicks the Remove link, but that’s a hard problem. If the user cancels out of the form, what do you do? You’ve already sent the DELETE request. Instead, lets add the Delete property to our phone number. We also need to show this on the form as a hidden field.

The code here is pretty simple. First, find the parent container of the element. That’s why we had to wrap our phone number with <div class="phoneNumber"></div>. We’re going to find the delete element inside that container and set it’s value to ‘True’. Finally, we’re going to hide the container. After clicking this link, we should see some POST data that demonstrates that this phone number has been marked for deletion. It’s important that we .hide() the block, and not .remove(). If we remove it, it’s gone, and it won’t get POSTed with the form.

Good, we’re making progress. Just one more piece, and that’s the add link. It’s not quite as easy as the remove link, and there’s a little bit of work to do here. I’m going to store the template content in the add link. There are other ways I could do this. I could send a GET request to the server, but this works and allows for maximum code reuse. First, I need to be able to encode my a string to make it JavaScript safe. Not HTML safe – we already have Html.Encode() for that. I want something similar to what Rick Strahl posted back in 2007. Here’s my version.

I don’t do too much differently. I ignore CRLF, because HTML doesn’t care about newlines. If you care about newlines, then you’ll need to uncomment the stuff at \n and \r. I’ve also compacted some of the redundant operators and removed the leading and trailing quotes. I guess (for now), you’ll have to trust me that my code works. Still, if you want other JavaScript encoding methods, that’s what search engines are for.

Adding a New Phone Number

OK, moving on. We also need a link and a helper for adding a new row. Here’s what Person.cshtml should look like now. Check out the last HTML helper.

Here’s what that HTML helper will look like. Yes, it’s got a few more input parameters. Let’s go through them. linkText is obvious. It’s the text that needs to appear on the link. The containerElement is where this block will be inserted in the HTML using a jQuery append method. The counterElement is how we’re going to count the number of items on the form. (Remember that we need to 0-index our properties.) collectionProperty tells us the prefix that needs to be added to the generated HTML elements. We didn’t need to worry about the prefix when calling the EditorFor method from the HTML source. Here, though, we’re not as lucky and need to do a little bit of MVC’s work ourselves. The helper method creates an instance of the object, generates the form using EditorFor.

So now we’ve got our link that says “Add Phone Number” on our screen. Here’s the HTML link that gets rendered by the above code. We do need to do a little bit of string magic. The elements generated by the EditorFor will be prefixed with nestedObject, and not PhoneNumbers[index] like we want. Our helper can change the text, but not the index. The lines with the “replace” method take care of making sure that our collection properties are correctly named. Instead of an index, though, I’m putting the system clock time in there. We’ll let JavaScript take care of figuring out what the real index should be. That’s where the addNestedForm() method comes in.

Recently working on exception and logging in a Ruby project I came across a nice gem called Minuteman which uses Redis bitmap to track user activity, further investigation shows that Redis can be used to track other metrics of your application very efficiently as well, last weekend I started to port in C# and thus Minuteman .NET version was born and nuget package is also available. Behind the scene it uses StackExchange’s BookSleeve as a Redis Client and as an added feature I have also utilized Redis built-in pubsub so that Signalr can be used to report real time update.

Minuteman contains UserActivity and EventActivity classes to track and report user and application events. Lets start with the UserActivity and see how it can be used.

Lets say, you want to track when a user logs into the system, to track:

await userActivity.Track("login", CurrentUser.Id);

Later on, you can check whether the user has logged into the system in a specific time frame like:

Behind the scene it uses Redis GETBIT, SETBIT and BITOP, so the result is extremely fast and since it uses bits to track the activity the data consumption is also very low.

UserActivity is best to track booleans but there are cases when we need to track how many times a certain event has occurred, in those cases the EventActivity comes into action. Lets say in your application you may want limit your api usage 60 calls per minute:

Both UserActivity and EventActivity has EventNames method that returns all the event names that you used for tracking. There is also a Reset method which you can use to erase the existing data.

To use the Pubsub both the class has a CreateSubscrption method which accepts the same event name that you pass in the Track method, it returns a Subscription objects which you use to Subscribe and later on Unsubscribe. But for the subscriber to comes into action the publishable argument of the Track needs to be true.

The Problem

In the previous article I showed how to load and populate an existing KnockoutJS view model which mirrored the properties of a C# model. There is an obvious problem relating to maintainability here; when the C# model changes we need to manually update the KnockoutJS view model. Fortunately there is a solution!

The Solution

To deal with this problem we can use the Knockout Mapping plugin which provides functionality to map JSON to KnockoutJS observables; you can either get it from the website or through NuGet.

If we simply want to map JSON to observables we can just use the mapping functionality of the plugin and use the return value directly as a view model. The example below demonstrates this usage:

Note the use of the ToJson() extension method from the previous article

While this approach works to create a simple model, it is more likely that you will want to have a more complex view model which defines functions and calculated observables. To accomplish this we simply need to create a typical KnockoutJS view model and use the mapping plugin within it:

The mapping configuration: used to customise the mapping process (beyond the scope of this series but the documentation may be useful)

The update target: the object to create observables in

In the example above the data is the C# model serialized as JSON and the update target is the “self” variable which references the view model object itself. This view model also defines a simple function which constructs and displays the Persons full name which can be bound to in the view. This view model can then be created and applied to the view:

While working on a new ASP.NET MVC project, I had a simple objective: add a new record and refresh my View. After sifting through several sites I found several resources that lead me to accomplish my goal.

I’ve compiled my result into a new sample MVC Application that I created in Visual Studio that you can download here. I’ll explain what I did using that as my reference. It’s a trimmed down version of what I did on the actual project, but it will get the point across.

Let’s assume we want to have a View that lists some People from our data source. I started out by creating a Person data model:

Next, I added a People folder in my Views folder and created a strongly typed Index View on my PersonIndexViewModel. I started out with building a table and doing a foreach to display each Person object. I moved that into a PartialView (.ascx) by creating a ParitialView in my Views/Shared folder (This blog post is very helpful for showing you how to use PartialViews). I called that PersonList.ascx and that is a strongly typed partial view on my PersonListViewModel.

Now, I can update my View to display that PartialView with this code:

<% Html.RenderPartial("PersonList", Model.PersonListModel); %>

Next, I want to be able to perform a delete action to remove a Person from the DB. You’ll notice I’m using an Ajax.ActionLink in my PersonList PartialView so that I can perform the delete with Ajax.

In the ActionLink, I specify the Action I want to call, pass the Person.Id and in the AjaxOptions I defined a JavaScript method that should be called on complete. In my People Controller I can now add the JsonDelete method:

You would call your Repository to delete that Person and then return a new Json Object. What I did was define a couple of properties that I will reference from the JavaScript function to give feedback to the user. Here is the JavaScript function:

One important thing here is the method “RenderPartialViewToString”. I ran across this which was a tremendous resource in solving my problem here, which was returning a Json Object with a rendered PartialView so that I could use JavaScript/jQuery to update the page.

The post I referenced above showed where you needed to create a base Controller to inherit from and that Controller defines the methods which will return a PartialView as an HTML string:

I have a div tag that surrounds my Html.RenderPartial call and I can use jQuery to just replace the HTML. Remember JsonAdd.PartialViewHtml contains the entire HTML of the newly rendered PartialView that we called from the Controller:

ASP.NET MVC 2 introduced a multitude of strongly-typed helpers for building form elements for strongly-typed views. These strongly-typed helpers use lambda expressions to build a complete input element, including the correct name and value for the element.

The lambda expressions are quite powerful, allowing you to build quite complex edit models and have model binding put everything back together again. A complex view model type such as:

As long as we’re using the full model expression from the top-most model type to build the input elements, the correct HTML will be built. Suppose that you want to now pull that PriceEditModel out into a partial, and keep its view separate from the parent view. We change our view to instead render a partial for the Price property:

However, the resultant HTML no longer matches up the model members correctly. Although the screen looks right:

When we look at the actual HTML, something’s not right any more:

Instead of our member name having the correct parent member in its name as “Price.Currency”, we only see “Currency”. Sure enough, when we get to our POST action, the Price member is null as model binding could not line things up any more:

Not exactly what we want to do here!

So what are our options? In order to make sure model binding works for models with partials, we can scope our models in our partials to the parent type. That is, make our partial’s model type “ProductEditModel” instead of “PriceEditModel”.

Not a very appealing option!

We do have a better option, with the MVC 2 feature of templated helpers. Templated helpers elegantly solve the deep View Model graph problem.

Building with templated helpers

Templated helpers are different than partials in that special contextual information from the parent is passed down to the child as long as we’re using the Html.EditorXyz() HtmlHelper methods. To convert our view to use templated helpers, let’s just build an editor template for each view model type we have:

These are just normal partials in Razor, with the exception that they’re placed in the special EditorTemplates folder. In our ProductEditModel partial, we just move what we had in our Edit view over:

There is one slight difference here, however. Instead of rendering a partial for Price, we render the editor for the Price member. The PriceEditModel template is just what we had in our original partial with no changes needed:

ASP.NET MVC will look at the type of the model to see if an editor template exists for that specific model type when we call the EditorForModel method. Because we built editor templates for each specific model type, it doesn’t matter where in the hierarchy these nested types exist. ASP.NET MVC will keep passing in the parent’s context so that deep nested graphs contain the right context information.

Looking at the resultant HTML, we can confirm that everything looks good there:

The input element’s name now has the correct parent property name in its value. Debugging into the POST action confirms that the model binding now works correctly:

With the templates helpers of ASP.NET MVC 2, we can now build nested models in our views and still take advantage of features like partials. The only caveat is that we need to make sure we build our views using templates helpers and the Html.EditorXyz methods. Otherwise, our views are minimally impacted.

And just to get a side complaint in, this was very annoying to build in MVC 1.0, to build nested hierarchies with strongly typed helpers respecting graphs including collection types all the way down. Just more code I got to delete with the later versions of MVC!

One of the common tasks I encounter periodically is submitting a simple array of strings or numbers from JavaScript to a controller method for processing. It seems like I struggle often trying to make it work. So, this time I decided to develop a simple and easy to use solution. I decided to utilize custom model binder capabilities available in ASP.NET MVC. To use this method you have to define a model and a binder that will populate the model. In my case my binder assume that the data is submitted as a post or a get, pulling the data from either form collection or query string collection from the request object. It also assumes that my array is the only data submitted. In my case my model has single property – List of strings. Let’s take a look at the code.

The code above check both form and query string trying to pull submitted data out of either. Then I use JavaScriptSerializer to push the data into the model. I could have used Json.NET just as well, but for demo purposes this is just as good. This is it. To consume this code just add ListOfStringsModel as your parameter to a controller method.

A few days ago we released the ASP.NET MVC 4 Beta. This is a significant release that brings with it a bunch of great new features and capabilities.

The ASP.NET MVC 4 Beta release works with VS 2010 and .NET 4.0, and is side-by-side compatible with prior releases of ASP.NET MVC (meaning you can safely install it and not worry about it impacting your existing apps built with earlier releases). It supports a “go-live” license that allows you to build and deploy production apps with it. Click here to download and install it today.

The ASP.NET MVC 4 Beta will also be built-into the upcoming VS11 / .NET 4.5 beta that is coming out shortly. This week’s beta doesn’t work with the previous VS11 developer preview that shipped last September – if you are using the VS11 Developer Preview (or have it installed) you’ll want to wait until the VS 11 beta is released before trying out the new ASP.NET MVC 4 Beta functionality.

ASP.NET MVC 4 Features

The ASP.NET MVC 4 Beta includes a bunch of great new features and capabilities. Some of the highlights include:

Bundling and Minification – ASP.NET MVC 4 includes the new bundling and minification support we are also adding to ASP.NET 4.5. These features enable you to build web applications that load faster and feel more responsive to users, by minimizing the number and size of HTTP requests that your pages make. Included with the MVC 4 beta are new “cache busting” helper methods that enable easy proxy caching of bundled files (with automatic invalidation if you change the cached CSS or JavaScript). You can learn more about bundling and minification from my previous blog post about it.

Database Migrations – ASP.NET MVC 4 includes the new Entity Framework 4.3 release, which includes a bunch of great new features. One of the most eagerly anticipated features it provides is database migration support. This enables you to easily evolve your database schema using a code focused migration approach – and do so while preserving the data within your database. I’ll blog more about this in the future – you can also see a walkthrough of database migrations in this tutorial.

Web API – ASP.NET MVC 4 includes some fantastic new support for creating “Web APIs”. This enables you to easily create HTTP services and APIs that can be programmatically called from a broad range of clients (ranging from browsers using JavaScript, to native apps on any mobile/client platform). The new Web API support also provides an ideal platform for building RESTful services. I’ll be blogging much more about this support soon – it is really cool, and opens up a bunch of new opportunities. There are several tutorials, samples and screencasts covering ASP.NET Web API on the ASP.NET site to help you get started.

Mobile Web – ASP.NET MVC 4 includes new support for building mobile web applications and mobile web sites, and makes it much easier to build experiences that are optimized for phone and tablet experiences. It includes jQuery Mobile, and includes new support for customizing which view templates are used depending upon what type of device is accessing the app. See the ASP.NET MVC 4 tutorial series.

Razor Enhancements – ASP.NET MVC 4 includes V2 of our Razor View engine. Razor V2 includes a bunch of juicy enhancements that enable you to make your view templates even cleaner and more concise – including better support for resolving URL references and selectively rendering HTML attributes.

Async Support and WebSockets – You’ll be able to take advantage of some additional language and runtime capabilities when using ASP.NET MVC 4 with .NET 4.5 and VS 11. Async support is one of the big ones, and the ASP.NET MVC runtime support for this combined with the new C#/VB async language enhancements (which are super elegant and clean) is going to enable you to write incredibly scalable applications. You will also be able to take advantage of the new WebSocket support built-into .NET 4.5 to build applications with even richer browser/server communication.

I’ll be blogging a lot more about the above features in the weeks and months ahead. This is going to be an exciting release. There is a lot there that will both make you more productive (Bundling/Minification, Database Migrations, Razor V2) as well as enable you to build even richer web applications and experiences (Web API, Mobile Web, WebSockets).

Learning More About ASP.NET MVC 4

I gave a tech-talk about the new ASP.NET MVC 4 Beta at the Belgium and Dutch TechReady events last week. It provides a good overview that you can use to quickly come up to speed on the release.

Summary

I’m really excited about the upcoming ASP.NET releases we have coming out this year. ASP.NET 4.5 and ASP.NET MVC 4 are going to deliver a ton of new capabilities and enhancements, and the tooling updates we have coming with VS 11 and WebMatrix make the developer experience awesome.