EX10: Building a Next-Generation Web Applicationwith ASP.NET

Building a Next-Generation Web Application
with ASP.NET MVC 2 and jQuery
Nate Kohari
Co-Founder / CTO
Enkari, Ltd.
[email protected]
Who?
Goals
ASP.NET is a great platform
for building attractive,
standards-compliant
rich internet applications
You can build rich internet
applications without
Silverlight or Flash
Why ASP.NET MVC?
BizSpark
Why jQuery?
(demo)
User
Action
Event
Broadcast
Metadata
Lookup
Anatomy of a typical
Zen request
Domain
Service
Route
Lookup
Filters
HTML/JavaScript
User
Action
Event
Broadcast
Metadata
Lookup
Domain
Service
Route
Lookup
Filters
ASP.NET MVC
User
Action
Event
Broadcast
Metadata
Lookup
Domain
Service
Route
Lookup
Filters
JS.Class
Zen.Ui.StoryCard = new JS.Class({
func1: function() { ... },
func2: function() { ... }
});
var card = new Zen.Ui.StoryCard();
Behaviors
$(“.story-card”).attach(
Zen.Ui.Behaviors.StoryCard);
Find all elements with the CSS class story-card…
$(“.story-card”).attach(
Zen.Ui.Behaviors.StoryCard);
$(“.story-card”).attach(
Zen.Ui.Behaviors.StoryCard);
…and apply the appropriate behavior
Which card did the
user move?
User
Action
Event
Broadcast
Metadata
Lookup
Domain
Service
Route
Lookup
Filters
(story card)
<li data-projectid=“123” data-storyid=“456”>
...
</li>
HTML5 data-* attributes
(story card)
<li data-projectid=“123” data-storyid=“456”>
...
</li>
HTML5 data-* attributes
{ projectid: 123, storyid: 456 }
JSON read via Metadata Plugin
Where should we send
the request?
User
Action
Event
Broadcast
Metadata
Lookup
Domain
Service
Route
Lookup
Filters
One Action = One Route
One Action = One Route
(“route-per-action”)
Routes defined in XML:
<app>
<project>
<route
action=“move”
pattern=“project/{projectid}/story/{storyid}/move”
verbs=“post”/>
...
</project>
...
</app>
Routes defined in XML:
<app>
<project>
<route
action=“move”
pattern=“project/{projectid}/story/{storyid}/move”
verbs=“post”/>
...
</project>
...
</app>
…at app start, parsed & registered in RouteTable
Routes defined in XML:
<app> (area)
<project>
<route
action=“move”
pattern=“project/{projectid}/story/{storyid}/move”
verbs=“post”/>
...
</project>
...
</app>
Routes defined in XML:
<app>
<project> (controller)
<route
action=“move”
pattern=“project/{projectid}/story/{storyid}/move”
verbs=“post”/>
...
</project>
...
</app>
Routes defined in XML:
<app>
<project>
<route
action=“move”
pattern=“project/{projectid}/story/{storyid}/move”
verbs=“post”/>
...
</project>
...
</app>
Url.Action(“move”, “story”,
new { projectid = 123, storyid = 456 })
Url.Action(“move”, “story”,
new { projectid = 123, storyid = 456 })
http://agilezen.com/projects/123/story/456/move
But wait… we need
the route in JavaScript!
urlfor()
urlfor(“move”, “story”,
{ projectid: 123, storyid: 456 })
urlfor(“move”, “story”,
{ projectid: 123, storyid: 456 })
http://agilezen.com/projects/123/story/456/move
urlfor(“move”, “story”,
{ projectid: 123, storyid: 456 })
Metadata read from story card <li>
routes.js
User
Action
Event
Broadcast
Metadata
Lookup
Domain
Service
Route
Lookup
Filters
HTML/JavaScript
User
Action
Event
Broadcast
Metadata
Lookup
Domain
Service
Route
Lookup
Filters
ASP.NET MVC
Aspect Oriented
Programming
[Demand]
[Demand(Permission.EditStory)]
[Secured]
[Secured(SSLMode.Force)]
[Transactional]
Output Filters
[DoNotCache]
[StripWhitespace]
[HandleExceptions]
User
Action
Event
Broadcast
Metadata
Lookup
Domain
Service
Route
Lookup
Filters
Filters
Security
Other cross-cutting concerns
Filters
Security
Other cross-cutting concerns
Controller
Interprets requests
Communicates with browser
Sets up view data
Filters
Security
Other cross-cutting concerns
Controller
Interprets requests
Communicates with browser
Sets up view data
Domain Service
Modifies data model
Broadcasts events
Filters
Security
Other cross-cutting concerns
Controller
Interprets requests
Communicates with browser
Sets up view data
Domain Service
Repository
Modifies data model
Broadcasts events
Persists data to database
Filters
Controller
LINQ
Domain Service
Repository
NHibernate
User
Action
Event
Broadcast
Metadata
Lookup
Domain
Service
Route
Lookup
Filters
Domain Service
Messenger
SMTP Service
XMPP Service
Domain Service
Events queued
Messenger
SMTP Service
XMPP Service
Domain Service
Events queued
Messenger
SMTP Service
XMPP Service
Domain Service
Events queued
Messenger
SMTP Service
XMPP Service
Email notifications
IM notifications
User
Action
Event
Broadcast
Metadata
Lookup
Recap
Domain
Service
Route
Lookup
Filters
Thanks for listening!
Nate Kohari
http://kohari.org
http://agilezen.com
[email protected]
@nkohari