Inside the ASP.NET Single Page Apps Template Beta | John Papa

John Papa

Evangelist on the loose

Inside the ASP.NET Single Page Apps Template Beta

...

There are a bunch of shiny new toys, including a new Single Page App (SPA) template, inside the ASP.NET Fall 2012 Update BUILD Prelease  ( Download link for it is on this page here ) . The original template for SPA made an appearance over a year ago in a preview and was later removed prior to VS 2012 being released. (You may recall Upshot.js was part of the former template before both of their demises) The first run at the former template wasn’t really a template, but rather a specific way to create a SPA. This new template is a template . Kudos to Mads Kristensen for spearheading this at Microsoft. Here is the sample app that they give you when you choose the new SPA template.

UPDATE: This post has been updated. There is a new version of this template in the ASP.NET and Web Tools 2012.2 (Release Candidate). You can read my latest post on this for more details. Most of the server side code has not changed, however the JavaScript has changed considerably and for the better in the latest version.

What Do You Get?

  • ASP.NET Web API Controllers
  • ASP.NET MVC
  • Authentication / Authorization
  • Sample DbContext with Entity Framework and some POCO Models and DTO’s
  • Bundling and Minification
  • jQuery
  • Knockout.js
  • Samples in JavaScript
    • models
    • a viewmodel
    • custom Knockout binding handlers
    • data access module

The template gets you started with the intent of helping you avoid the “blank page” syndrome and instead having a starting point for creating a SPA. Where you take it from there is up to you. This is especially important since there are many good ways to create a SPA.  The key takeaway use it as a starting point to get you going.

For more information about SPA’s you can refer to my SPA blog post series or watch my video course on building Single Page Apps.

Let’s start by examining exactly what’s inside.

DbContext

They toss a very simple sample DbContext at you based on Entity Framework. You can obviously swap in and out whatever you want here.

public class TodoItemContext : DbContext
{
    public TodoItemContext()
        : base("name=DefaultConnection")
    {
    }

    public DbSet TodoItems { get; set; }
    public DbSet TodoLists { get; set; }
}

Models

The template comes with a series of models and Data Transfer Objects (DTO’s). It’s interesting that they decided to use both models and DTO’s which are intended to be vessels for the models’ data to send to the client.  This does offer more separation of models from DTO’s but I’m not sure I’d have gone this route with a template. I’d instead start with the models and not add the DTO’s til I actually needed one. (Or possibly I’d use a projection, but that’s a tale for another time.)

Web API Controllers

The template comes with a TodoListController and a TodoController.  They both have the [Authorize] attribute on the web api method calls, which is a good practice. The TodoListController has several methods for CRUD including a GetTodoLists (which gets all of the todo lists). It returns an IEnumerable (though with the new features it would be more interesting to return an IQueryable). Notice the code below retrieves the  Todo entities and then creates the Todo DTO’s from them, before returning them to the caller. Pretty straightforward. Of course, they also have the CUD method from CRUD (Create, Update and Delete).

    [Authorize]
    public class TodoListController : ApiController
    {
        private TodoItemContext db = new TodoItemContext();

        // GET api/TodoList
        public IEnumerable GetTodoLists()
        {
            return db.TodoLists.Include("Todos")
                .Where(u => u.UserId == User.Identity.Name)
                .OrderByDescending(u => u.TodoListId)
                .AsEnumerable()
                .Select(todoList => new TodoListDto(todoList));
        }

The key takeaway here is how simple it is to set up your database, Entity Framework and API controllers to get you rock and rolling very quickly. It’s a very scaled down version of what I did in my Code Camper SPA and a great starting point. So what do you do with this part of the demo? I’d start by deciding how you want your Entity Framework code to look and if you want to use it as your repository and Unit of Work or you want your own Repo and UoW on top of EF (what I did in Code Camper). Both are good choices. Next I’d decide on your structure for your Controllers. I like Separation of Concerns (SoC) and recommend making your controllers responsible for pushign and pulling data. THis means making sure you don;t add business logic to this layer. For that, I like the Controller to call a business manager layer who is responsible for handling all the heavy thinking. Finally, decide if you want or need custom DTO’s … I start without them and only add them if I see a need.

The View

The code below comes form the index.cshtml view inside of the Views/Home folder of the sample app. Notice it starts off with a quick check to make sure the user is authenticated. If they are not, it shows a login page (not shown below), but if they are authenticated the page displays the available Todo lists. This is a simple way to add some authentication to your app using some built in ASP.NET features.

@if (@User.Identity.IsAuthenticated)
{

}

Then, inside of the if statement is all of the HTML and the bindings for the View.

<button data-bind="click: addTodoList">Add Todo list</button>
<a class="deletelist" href="#" data-bind="click: $parent.deleteTodoList">X</a>
 

Data Binding with Knockout

Notice some interesting data binding features, that use Knockout.js. You can create a list using Knockout’s click binding which calls the addTodoList method. This method binding invokes the addTodoList method on the JavaScript ViewModel.

<button data-bind="click: addTodoList">Add Todo list</button>

The ViewModel also exposes a todoLists property which will be iterated over using Knockout’s foreach binding. Notice the entire section is visible only if there are any todo’s (using Knockout’s  visible binding). It’s often a good idea to use the visible binding to hide and show DOM elements instead of adding and removing them. DOM manipulation is very expensive in browsers, while hiding and show is often much faster.

You could bind the visible binding to any expression that is truthy or falsey, like this: visible: todoLists().length


They also included a few custom Knockout binding handlers:

  • validate – invokes jQuery validation on an element
  • selected – selects (or unselects) a DOM element based on the bound property’s value
  • blurOnEnter – loses focus when the user clicks the ENTER key
  • placeHolder – a shim for the HTML5 placeholder for older browsers

The key here is not that actual binding handlers but rather that they show you a simple way to extend Knockout’s binding structure to add your own features. I do this in my Code Camper SPA to create simple handlers like escape (which performs an action when the ESCAPE key is pressed) and more complex handlers for thing s like a  custom starRating control.

Once inside of the view, another foreach binding is used to iterate of each todo lists’s todos. Here the checked binding checks or unchecks a  checkbox, the value binding displays the values for INPUT type=”text” elements, the visible binding shows or hides an error message (for validation , and the click binding calls the $parent.deletTodo method. $parent is a feature in Knockout that let’s you go up one (or more) levels in the datacontext hierarchy. In this case the binding is to a single todo item. The deleteTodo  happens on the parent level (at the Todos list level), so to get there we have to reference $parent to get back up to that level first, and then delete it. You can learn more about $parent at the Knockout site or in my Knockout course at Pluralsight.

JavaScript Models

You get a sample model for the TodoItem and TodoList, as well as a TodoListViewModel (these are located in the todoList.js file). The TodoItem function is a constructor for an object that has properties for the Todo model (Title, IsDone, TotodItemId, etc) that are mapped from the DTO passed from the Web API. It also has some additional members that are not derived form the server nor the DTO such as a save method and a ErrorMessage property. The ErrorMessage property is an observable that can be set to display valdiation information about the object. The save method defers the save to a method in the dataAcess module (more on that in a moment) which returns a promise.

function TodoItem(data) {
    var self = this;

    // Persisted properties
    self.TodoItemId = data.TodoItemId;
    self.Title = ko.observable(data.Title);
    self.IsDone = ko.observable(data.IsDone);
    self.TodoListId = data.TodoListId;

    // Non-persisted properties
    self.ErrorMessage = ko.observable();

    self.save = function () {
        self.ErrorMessage(null);
        return TodoApp.Db.saveItem(self)
            .fail(function () {
                var message = self.TodoItemId ? "Error updating todo item." : "Error adding todo item.";
                self.ErrorMessage(message);
            });
    };

    self.del = function () {
        return TodoApp.Db.deleteItem(self.TodoItemId)
            .fail(function () { self.ErrorMessage("Error removing todo item."); });
    };

    // Auto-save when these properties change
    self.IsDone.subscribe(self.save);
    self.Title.subscribe(self.save);
}

This is a basic CRUD example but it certainly has some great starting points that you can build from.

One thing I don’t like here is that the models have awareness of how to save themselves. It’s not “wrong”, but I prefer my models to be data stores while another module is responsible for handling the data awareness. This Separation of Concerns means I have models that hold the data on the client and a module that handles that getting and saving of its data. I have called this other module things such as datacontext (its name in my SPA course) or datamanager in the past.

JavaScript ViewModels

The sample comes with a ViewModel named TodoListViewModel (shown below). Think of it as “The View’s Model”. The View needs data. The models store the data. But the data is not in the format the view needs it in. So the ViewModel pulls the data from the models together and presents it in a way that the View requires. This is also known as the Model-View-ViewModel pattern (MVVM).

The ViewModel also adds additional features such as awareness of the the models, reference to the client side data services (todoList.dataAccess.js) for getting and saving data in the models, and validation/error information. Its the presentation logic for the View.

function TodoListViewModel() {
    var self = this;
    self.todoLists = ko.observableArray();
    self.error = ko.observable();

    // Operations for the Todo List
    self.addTodoList = function () {
        var todoList = new TodoList({ Title: "My todos", UserId: "to be replaced" });
        self.todoLists.unshift(todoList); // Inserts on client a new item at the beginning of the array
        todoList.save();                  // Inserts on server
        todoList.IsEditingListTitle(true);
    };

    self.deleteTodoList = function (todoList) {
        todoList.del() // Deletes on server
            .done(function () { self.todoLists.remove(todoList); }); // Deletes on client
    };

    // Load initial state from server, convert it to TodoList instances, then populate self.todoLists
    TodoApp.Db.getLists()
        .done(function (allData) {
            var mappedTodoLists = $.map(allData, function (list) { return new TodoList(list); });
            self.todoLists(mappedTodoLists);
        })
        .fail(function () {
            self.error("Error retrieving todo lists.");
        });
}

Modules

The sample follows a very simple form of a module pattern. It encloses the modules (ex; models and viewmodels) in an unnamed closure to help get the modules out of the global namespace. It’s a good starting practice, though I expanding on this pattern with its big brother the  Revealing Module Pattern.

(function () {

// All models and viewmodels are in here

})();

Data Service

The data service (aka the todoList.dataAccess.js) module handles all of the ajax requests. So the viewmodels and models call this to get and save data. I do this in my course too in a module called dataservice.js which handles it via amplify.js (using jquery to make the ajax calls). Both my course’s SPA and the sample follow this separation of data services, which I really like so it keeps the ajaxian plumbing out of my viewmodels.

(function () {
    window.TodoApp = window.TodoApp || {};

    // Private: Routes
    var todoListUrl = function (id) { return "/api/todolist/" + (id || "") },
        todoItemUrl = function (id) { return "/api/todo/" + (id || "") };

    // Private: Ajax helper
    function ajaxRequest(type, url, data) {
        var options = { dataType: "json", contentType: "application/json", cache: false, type: type, data: ko.toJSON(data) }
        return $.ajax(url, options);
    }

    // Public: Db methods
    window.TodoApp.Db = {
        getLists: function () {
            return ajaxRequest("get", todoListUrl());
        },

        saveList: function (todoList) {
            if (todoList.TodoListId) {
                // Update
                return ajaxRequest("put", todoListUrl(todoList.TodoListId), todoList);
            } else {
                // Create
                return ajaxRequest("post", todoListUrl(), todoList)
                    .done(function (result) {
                        todoList.TodoListId = result.TodoListId;
                        todoList.UserId = result.UserId;
                    });
            }
        },

        deleteList: function (todoListId) {
            return ajaxRequest("delete", todoListUrl(todoListId));
        },

        saveItem: function (todoItem) {
            if (todoItem.TodoItemId) {
                // Update
                return ajaxRequest("put", todoItemUrl(todoItem.TodoItemId), todoItem);
            } else {
                // Create
                return ajaxRequest("post", todoItemUrl(), todoItem)
                    .done(function (result) {
                        todoItem.TodoItemId = result.TodoItemId;
                    });
            }
        },

        deleteItem: function (todoItemId) {
            return ajaxRequest("delete", todoItemUrl(todoItemId));
        }
    };

})()

Good Starting Point

If you are looking for a starting place, this is a good choice. It gets you going quickly and provides a good foundation for you to build on. The key here is to not use this as law, but use it instead as guidelines from which you can deviate where it makes sense for you. Some deviations will be to use your own choice of libraries instead of what they (or I) prefer. Some choices will be to decide to use different separation concepts like how I prefer my models to not have a “Save” method. The goal of this template seems to be to give folks a place to start and provide them enough information to choose their own adventure beyond that. I believe it hits that mark.

Choose Your Own Adventure

My only concern is that some folks may not explore beyond the template. So where might you go from here and what deviations might you want to make? This template doesn’t do it all as this wasn’t its intention. Again, its a good starting point. Here is a small set of functionality that you may want to add to the SPA:

  • Multiple Views
  • Page navigation between the Views
  • Change Tracking
  • Synching data between Views and ViewModels
  • Saving and restoring from Local Storage (tombstoning)
  • Caching data on the client
  • Filtering, sorting, paging, ordering on the client
  • Responsive design and UI concepts
  • Reverse ajax for server to client communications

You can add in your own custom libraries or pull in 3rd party libraries such as Sammy for navigation, Breeze for rich data, SignalR for reverse ajax, or Amplify for local storage. You could use a javascript pattern to keep you organized. You could write the app with TypeScript which is especially helpful if you come from a static language background or if you want to start using ECMAScript 6 features now. If you want ot learn more about TypeScript, keep an eye out on Pluralsight in December for our TypeScript course (I am co-authoring with Dan Wahlin). If you want to see more about these features, you can check out my Single Page Apps blog post series and my Code Camper SPA course with Pluralsight.

There are a lot of directions you go from here and by no means are you done once you open this starter template which puts you on a road for your adventure. But that is the fun of a choose your own adventure.

 

tags: html5 javascript knockout mvvm SPA visual studio 2012 web api
  • Pingback: Inside the New Single Page Apps Template | John Papa | WebDevStuff | Scoop.it

  • http://www.bizcad.com Nicholas Stein

    I have been working through building an spa based upon your latest Pluralsite course. The back end is done and I am starting on the front end. I found your data layer a bit daunting. I started working with breeze.js and I got their ToDo app working but have not gotten much further. I am waiting with bated breath to hear about your latest experiment with breeze.js. I wanted to go to Las Vegas, but yours was the talk I was really interested in and I could not afford the time away from my client right now.

    I watched the Ch9 stuff and I may give this new SPA template a chance. The ajax data layer looks pretty easy to understand. I believe I can plug in breeze.js into it without too much trouble.

    • John

      Thanks for the feedback. The new spa template is a nice starting place, but keep in mind there are very few few in that. That’s on purpose. The template is just a jumping off point. You can certainly add breeze to it and really take it further. Then you can add navigation, cuz I assume you want multiple views.

      I’ll be posting code camper jumpstart next week. Then I’m moving on to create campers spa intro course for pluralsight.

      I’ll be speaking about spa at http://www.devintersection.com in Dec at a full day workshop, too.

  • Hasan Yiğit Özbahçe

    Nice blog John.

    I guees it is time to make things a bit easier by using Typescript or CoffeeScript. Static-typing in Javascript is the next big thing coming. So I hope, if you can find anytime you can work on one of those 2 as well.

    • John

      Yep. Im working on a Typescript course now with Dan Wahlin for PluralSight. :-D

  • Quentin

    Hi John, I watched your CodeCamper series on PluralSight and am blown away. I did loose a bit of track on the front end as there are so many lib’s used that I am not all that familiar with. I have used the same backend but am using Fluent NHibernate with a “switcher” option to use EF. I personally think NH is much faster :)

    I have also dropped the MVC portion and am using pure html and Javascript. I rolled my own “View Switcher” instead of sammy, but might go back to that as I am using OData for the backend instead of MVC Controllers, but I want to build a “proxy” which will sit between the OData service and the client site… for security.

    What would be great is a Visual Studio 2010 version of the Code Camper app. I have VS2010 at the office and cannot open your app there.

    The template is fantastic, but I do tent to agree with you about the models, DTO’s etc. The only trouble I had with your Code Camper method was that I was getting circular references from EF when exposing my models.

    PS: I must say, your series is fantastic…. but using the same cassing for your own properties and that of EF made it tricky to keep up… e.g.: DbContext DbContext = new DbContext(); <- which is which!? LOL

    • John

      Hi Quentin,

      There are several libraries in JavaScript, but think of them as the many references in a .NET project. We tend to pull them in over time and slowly learn new ones. Just like DLL’s, I tend to avoid a library or UI widgets until I need them. No need for a dependency unless you see a need.

      You can certainly use page navigation on the server. That’s standard web app architecture and works great. The client side navigation is what helps give you SPA. Its just a choice you make.

      There is link to a helpful post to get your solution to VS 2010. You can check it out here: http://www.johnpapa.net/opening-code-camper-in-visual-studio-2010/

      Glad it’s been useful!

  • http://daveymcglade.net Davey

    Great stuff John, thanks

  • Nat

    Hi John,

    How about an introductory course on SPA using this new template as a starting point?

    C’mon, please… Please!

    • John

      Yep, already in the works. Right after I finish up a TypeScript Fundamentals course with Dan Wahlin.

  • Nat

    Awesome! This is just what I (and others) need.

    John Papa, + 1 Legend.

  • Pingback: Links of the week | Jan @ Development

  • Quentin

    Hey John, thanks for the VS2010 link. I missed it on the front page, arrived here via twitter message :)

  • Matthew Paul

    Hmm, I’ve followed the download link, but I see no SPA template in VS 2012. What am I missing?

    • Ken

      Select MVC 4 first and then you will see the SPA template, else use devenv.exe /InstallVSTemplates.

  • Ryan

    Your code highlighting is double encoding HTML entities, e.g. greater than symbols show as >

    • Ryan

      and apparently the comment box un-html encodes comments.

    • John

      Ryan,

      Thanks for the feedback. We’re still working out a few of the site’s new design issues. This is one of them :) I expect we’ll get that fixed very quickly.

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1226

  • MattPil29

    Hi, I was just wondering if there is a reason why the SPA template uses System.Web.Mvc.Controller and not System.Web.Http.ApiController? Surely SPAs lend themselves to a Web API infrastructure and not ASP.Net MVC4.

    Matt

    • John

      Matt,

      There are both in the SPA preview template. The Api controllers use ApiController and there are also regular Controller classes too.

      • MattPil29

        Just typical, I checked the account control and not the ToDo one! Thanks for the reply….

  • Pingback: Inside the New Single Page Apps Template | John Papa | News de la semaine .net | Scoop.it

  • Dizzyguy

    According to this blog (http://dotnet.learningtree.com/2012/04/03/working-with-the-entity-framework-and-the-web-api/) future versions of Web api (and JSON.Net) will eliminate the need for DTO’s and/or projection. Seems this all should piece together a bit more seamlessly. Any thoughts?

    • John

      Hi Dizzyguy,
      That would indeed be good for when DTO’s are needed. However, sometimes DTO’s aren’t needed at all either if you are able to return the same object (which is often OK if you keep your models more like a DTO with POCO). But yes, that would be great!

      • Dizzyguy

        Thanks John. You cleared up some confusion on my part actually. Look forward to your Pluralsight course on Typescript.

  • Jeff M

    John – this is a repost from your Part 6- JavaScript Modules section. But it looks like it belongs here:

    ——

    TypeScript doesn’t support non-anonymous define statements. Is it trivial to remove the module names from CodeCamper? Do you have to optimize with require.js?

    Any insight here would be great. Looking forward to your TypeScript presentation. I’ve reviewed your (6 hour!!) SPA presentation twice!

    Jeff

  • Pingback: Single Page Apps – Live at the LinkedIn .NET User Group | John Papa

  • Jeff M

    Ok… well, adding TypeScript to the CodeCamper project isn’t as trivial as I had hoped. Using TypeScript and AMD still has some significant problems. For example, I’m struggling to import third party libraries (such as jQuery) into TypeScript external modules. Using TypeScript to create javascript AMD modules such as: define (“moduleName”, [jQuery, Breeze], function ($, Breeze) { }) don’t yet seem possible.

    Hopefully, this is something that will be covering the upcoming Pluralsight TypeScript lesson.

  • Pingback: Cheatsheet: 2012 11.01 ~ 11.18 - gOODiDEA.NET

  • http://pontonetpt.org/blogs/guilhermecardoso/ Guilherme Cardoso

    Is there anyway to get a sample of this template without VS 2012?

    I don’t have Windows 7 on my PC so i have to work with VS 2010, but i would love to check the code this SPA template so i can improve a project where i’ve implemented something similar.

    Thanks!

  • Carl

    I love your SPA stuff John, but as others on here have said, the code camper app is overwhelming with complexity for newcomers to this. I’m an asp.net forms programmer, used to LINQ to SQL generated classes so your SPA approach is a sea change for me. I’ve spent some time doing more backend reading and experimentation and I worked through your code camper presentation again recently (doesn’t help that I use VB and not c# but I can just about cope with that!). This time through it was easier to follow, but there is still much that is bewildering.

    Then this new, simple SPA template appears, far more cut-down and far more understandable. Looks brilliant and I thought I was getting somewhere. Then I got to the bottom of your piece and (to paraphrase) saw the “this is ok, but you shouldn’t really do it this way, you need to add this, that and the other…” and that’s just really frustrating as it almost instantly renders the template obsolete or at least not as good as it could/should be. Why have a template that promotes bad practice?

    Well that’s all well and good but I’m sure there’s more than just me now looking on in frustration thinking “it’s great saying we should plug Sammy in or add breeze… but HOW do we do this John!?” What would be incredibly useful is to start with this SPA template and have some simple walkthroughs to take it to a (still) simple SPA but add in a couple more pages with Sammy navigation and add some breeze interaction and let’s have some revealing module patterns. It’s almost impossible for us beginners in SPA to deconstruct the complexity of the code camper app as there’s just so much going on.

    • John

      Carl,

      Thanks for the feedback. The only question I saw was “how” to plug in breeze and sammy. I showed how to plug sammy in using my first Pluralsight SPA course. Breeze … I will be showing that soon. Breeze was not ready when I wrote that course. So that will come.

      You had many other excellent points that I hope to help clarify for you. I think your main point is that you;d like some more direction on how to do some of these things. So the short answer is, I’m thrilled that you want more SPA guidance/examples and I am planning to create more courses for Pluralsight to go through those scenarios to help folks of all experience levels build SPAs.

      Why did I wrote the SPA end to end course first?
      When I set out to start explaining SPA I had to choose what to hit first. Through experience, I felt strongly that if I showed a very basic SPA that was easy to get started with that folks would instantly be able to do it, however many folks wouldn’t have known what a SPA can do. Nor why they should use it at all. So I decided to first show what you can build and break it down. Next on my list is to begin a series of courses to show different aspects of the SPA. In fact, very soon I will be writing a course using the new SPA template that just came out in RC form Microsoft 2 days ago. In other words, yeah, I know its a lot to take in and I’m preparing a series to show how to do it.

      Consider if I had done the simple course first with just the things in the Microsoft SPA template. I’d be getting a ton of emails from folks asking how in the world to do rich data, dependency mgt, page navigation, handling object graphs, local storage, responsive design, calling the web api, and so on. My point is that there was not perfect answer. I’m just trying to help clarify by giving as complete an example as I could at the time. In fact, I left out a bunch of features just to try and keep it simpler (signalR, security, rich data, exporting metadata for validation, and more). I will hit those later though.

      SPA Template from Microsoft
      Regarding the current SPA template from Microsoft, it certainly is more cut down and understandable. It only has a few moving parts and significantly less features. It is a template from which you can start, and it serves its intention very well. Microsoft intended to get folks started but not be prescriptive on which libraries you use nor how you complete it. You can talk to them if you disagree with this approach as I am sure some feel they should tell you exactly how to do it, and others feel they shouldn’t.

      BTW – Microsoft updated their SPA template and used many of the patterns I already employ in my SPA course with Pluralsight (revealing module, separation of files, organized folder structure, and more). I’ll be blogging about this in the next few days.

      Where do you go from here?
      Just like you can add DLL’s to a .NET project, you can JavaScript libraries to a web project or SPA. If you don’t want navigation, don;t add Sammy (or history.js, etc). If you don;t want rich data, don’t add breeze.js. If you don;t want modularization or dependency management, don;t add require.js. You get the point :). These things are not necessary in an app, but they solve some needs that are very common. You can certainly start with the SPA template, but notice they did not use any of that. If you want those features or others, you need to either build them yourselves with JavaScript or pull in a library that helps you (or skip those features).

      I’m here to help and I plan to create more courses for Pluralsight in the near future, and some blog posts.

  • Ward Bell

    Sweet stuff, here John! Of course I’m pleased to see the interest in Breeze. Heads up, everyone, we’re close to sharing a Breeze version of the SPA Template with the world. Have a working example now. Just needs some documentation and templatizing.

  • Carl

    Thanks John

    I’m very much plugged in to what you’re doing and I’m fully committed to changing to this development style from classic web winforms. It will be really useful to see your upcoming tutorials and blog notes, so thanks for that.

    I fully appreciate your reasoning behind creating the codecamper app now you explain it. I think that my (and a few others from questions I’ve seen) problem was a lack of fundamental understanding of how some of these things worked as MVC was new to me, so was EF as was a whole lot of the js stuff. I started with your codecamper tutorial and basically spend time creating a vb.net version of it. It’s still not completely done but it’s almost there now. This way I learned other bits and pieces about how the behind-the-scenes stuff fitted together.

    I then watched Steve Sanderson’s channel9 video on upshot… then found out it was discontinued and dived into breeze instead and during the course of that I discovered more about how some fundamental javascript things worked that I hadn’t been sure about before.

    It was when I found this blog post and worked through it that a few more lightbulbs went off and I managed to get back into the codecamper app and understand a whole lot more about how things worked. It’s still very complex and it’s still hard to put it all together but I’m a whole lot closer now, thanks for that.

    I’ll stay tuned to learn more and I’ll also get looking at some of the other resources you mention thanks. One last thing… my impression (probably lack of understanding!) is that amplify and breeze tread on each others toes a bit with the local storage thing? Are amplify and breeze really complimentary or is it possible to go one way or another? I think what would help noobs like me gain better understanding is almost a diagram that shows (a bit like you did in your course with what knockout achieves over jquery) which bits of codecamper/ms spa template can be taken over/removed by the js libraries we’re discussing!

    • John

      Carl,

      Thanks for the conversation. I know others feel like you do :)

      I wish I could move faster, actually … but I write courses at night so it is limiting my production rate. LOL So much I want to share … at least I have a full plate over the next year. Perhaps I will blog about my next few course ideas, so folks know what is coming. Kind of a roadmap.

      You raise an interesting point about web in general. There are folks folks coming into SPA development concepts from WinForms, ASP.NET web forms, WPF, Silverlight, and MVC … not to mention non Microsoft tech. So getting up to speed on basics for MVC and JavaScript and JQuery are certainly helpful first. I find it tremendously interesting how many people of different backgrounds are heading in this direction. It’s pretty exciting.

      There is a small overlap with Breeze and AMplify. Amplify does 3 things well: local storage, messaging, and http requests. With Breeze, you can do http requests, so you don;t need amplify for that. But for local storage or messaging amplify is still useful. Also, amplify allows you to easily mock objects. Amplify is not crucial to the puzzle, its more of a helper. Breeze is something I am starting to put in the “must have” category. It basically replaces my entire module 8 on the data context. I’ll be dedicating much more to this topic in the near future.

      Hope this all helps, and thanks for watching my courses!

  • Pingback: Inside the ASP.NET Single Page Apps Template | John Papa

  • Tzvi Kaidanov

    So, even though I’m developing with MVC I could publish SPA apps in Android , Windows 8 and IOs using phonegap , or it’s not possible due to the Razor MVC Helpers that would fall without the asp.net framework ?

  • Pingback: MVC Single Page Template Update for ASP.NET and Web Tools 2012.2 RC - .NET Web Development and Tools Blog - Site Home - MSDN Blogs

  • Pingback: MVC Single Page Application Template Update for ASP.NET and Web Tools 2012.2 RC | MSDN Blogs

  • MikeS

    As others might have mentioned, and I might have seen if I actually RTFA, I think the DTO’s are all wet, as in not DRY. Also, I think this is a boat load of code for just a TODO list app, admittedly it is slick (though not without defects) and has more going on in it than TODO maintenance, but I don’t think I would allow myself or anyone to check in this code base as starting point for anything in real life, too many smells. I am not liking the 6 occurrences of “UserId != User.Identity.Name”. Forget that little nugget and you have a hole. And I guess one big thing is, is how the app responds to nonsensical input, given how noob programmers always overlook this, and for whom this sample is intended.

  • http://haidermrizvi.com Haider M Rizvi

    Thanks for the post……………really great stuff….

  • Pingback: New ASP.NET Single Page Application Template - Gunnar Peipman's ASP.NET blog

  • Guillaume

    I’m very glad that the SPA Template is back to VS2012. The only thing that bother me is that the project generated by the Template is not SPA but a Knockout exemple. Login/Logout makes you change page, and there is no illustration of SPA’s page navigation.
    It’s sad because the project illustrate most keypoints of doing SPA with ASP.NET MVC.

    • John

      Guillaume – I agree that a SPA should have page routing. Regarding the login page, the value there is to show how to integrate a login into a SPA, which very few samples do (notice mine doesn’t). There is nothing wrong with a SPA having more than 1 server side view, either. A SPA doesn’t have to be a single View on the server. The goal is to reduce round trips, but it would make little sense to make one massive View with every possible screen in it. A large app could have 25, 50 or 100+ Views and I wouldn’t want all of those loaded all the time. So I have no problem with the login page, and to extend that, I would design my app to have more than 1 View if the context of the screens was completely different (such as login or shifting to an admin section).

  • Ella Mapple

    Scrum is undeniably the winner of the agile
    method wars. Thanks to the ‘s vast network of
    Scrumstudy Certified Trainers and
    Agile
    Certification
    Courses.

  • Kylie Wilson

    Organizations need to be assured the individuals that
    manage their projects can integrate methods to achieve sustainability goals and
    still achieve project specific objectives. Project Managers need credentials
    that validate their proficiency with these specialized qualities. PMP Certified and scrum
    certified project managers can learn, apply, and validate mastery of
    sustainability based project methods to meet these demands

%d bloggers like this: