121
ASP.Net MVC 4 all - E J Hernández Valdelamar June, 2010 ASP.Net MVC 4 all Martial coding for rapid web development. Eugenio Jacobo Hernández Valdelamar México. Version 4. June, 2010

ASP.Net MVC 4 All

Embed Size (px)

DESCRIPTION

Eugenio Jacobo Hernández Valdelamar. ASP.Net MVC framework web programming notes & tutorial. July, 2010.

Citation preview

Page 1: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

ASP.Net MVC 4 all

Martial coding for rapid web development.

Eugenio Jacobo Hernández Valdelamar

México.

Version 4. June, 2010

Page 2: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

1 Introduction

So you want to make a Web application. Well, there are tons of information around the Internet and so many

languages and tools.

However, when you choose one, there is a learning curve to climb, so this decision is crucial for the next weeks,

months or years of your pro life.

But, what do you have to consider?

Language must be something known to you or easy to learn if it´s something new. Maybe, you don't want to pay

for a tool because you want to evaluate it. Web infrastructure must be at hand, so your computer must be able to

host a web server. Maybe you read some articles and top 10 lists to make sure you are on the right track or just

because you want to be part "on the right side" according to statistics.

While you analyze and decide what is the best choice for your career, I pick Microsoft web platform. I know VB.Net

for a while (desktop flavor), I have the tool (Visual Studio 2008) and the environment (virtual machine server with

Internet information server), and because I don´t want to start with 1990's ASP, I want to start with the most

recent incarnation of MS Web development alternatives: ASP.Net MVC framework.

In this document I´m planning to expose the main concepts and techniques to develop a Web application using this

platform.

So let´s start.

1.1 About this document

This document started as a compilation of references to try to understand ASP.Net MVC framework and how to

develop an application with it.

However there were lots of details about web applications, the ASP.Net framework and design criteria that I

wanted to unify to have a clear vision about this technology.

Another reason is that many articles in the web (some dated from 2007 or earlier) show code snipplets that don´t

apply to the current release of the framework; decorating action methods with attributes or changing views code

behind are deprecated, so its important to have an actual version of this code.

It's a "follow the breadcums" exercise and once I had a bunch of them, it was time to order all this jigsaw pieces to

get the big picture.

That's how these notes began to grow, and some readings about martial arts gave me the idea of organizing the

contents: theory, techniques and applied sets of techniques to solve problems (katas).

Page 3: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

1.2 About the author

Well, I've been teaching since 1993 and programming since 1990. I started with Turbo Pascal, then Turbo C++, had

some courses of mystic languages (Smalltalk, Prolog), had a taste of Java in the server side and I met Visual Basic in

1996. Since then I've been developing solutions with MS technologies, most for desktop and C/S.

Even when today I am more involved in software processes and methods, I like to be aware of technology

evolution, and I really think that web applications are about to make a great leap.

I still enjoy a lot programming and learning something new, and I believe this is a good opportunity to share the

experience.

Please, send any comment and suggestion that help me improve this work to:

[email protected]

1.3 Licence

This work is licensed under the terms of the Creative Commons Attribution- Noncommercial-No Derivative Works

3.0 License.

1.4 Document versions

Version 4. June, 2010.

Subsonic discovery. Intermediate sections draft. ASP.Net MVC 2 release.

Version 3. August, 2009.

Update on views realm. One more basic kata (sending e-mail), fixing tips and new PDF document format.

Version 2. June, 2009.

Format revision. File uploader sample. RSS sample. Basic techniques updated. Initial structure of intermediate

techniques (app design & testing). Initial structure of the intermediate techniques chapter.

Version 1. May, 2009.

Basic document structure (key concepts, basic techniques and code katas) and initial content.

2 ASP.Net MVC: key concepts

2.1 Web pages are not enough

Page 4: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

When you start dealing with web development, the basic thing you start playing with is HTML.

All you have to do is creating a file with .html extension, write some tags and the result in a browser will be a web

page.

Lets put something clear: writing HTML is NOT programming. HTML is a way to format content that will be

displayed on a browser.

You can be a masochist and write your pages in a text editor like Note Pad, or have a life and use a Web page

editor. Even you can use Office Word and then export the document to a Web page. Of course, this is only about

contents; the aesthetic part still remains in the graphic artists realm, and because I don´t want to mess with color

theory I'll keep it as Spartan as possible.

As long as your content remains static, this is the way to go. But if you want to add some notes every day, display a

calendar, have a list of your visitors or any functionality that implies new data, making it by hand is a bad idea

(unless you want to be buried alive in a server farm).

Interaction, nice look & feel and fresh data implies programming and something to put the text, numbers or

images you want to use.

2.2 Web applications See document: smli_tr-2007-166.pdf

So you want to make an application. Well, then you have to write some code to make a program. But where is this

programs is going to live? In your PC (win or *nix), in a big machine, in your cell phone? Well the answer tends to

be everywhere, and that means that your environment is the World Wide Web.

Current web applications rely extensively on a number of technologies that are fundamental components

of the web browser. These include the HTML markup language, Cascading Style Sheets (CSS), the JavaScript

scripting language, and the Document Object Model (DOM).

In a way, these technologies serve as the logical equivalent of “binary code” of traditional software applications,

and are intended for execution in any web browser regardless of the underlying hardware or operating system.

2.2.1 Database driven Web sites

A data-driven Web site draws its content from external dynamic data sources. The data sources may come from:

Page 5: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

* Files (text or XML)

* Database (SQL Server, Access, Oracle)

* XML Web services

* Other websites

When you have a data-driven site, you are collecting data on the fly and then building the pages from that data.

A well-architected, data-driven Web site is much easier to maintain than a static Web site because most content

changes require no change to the HTML behind the Web site.

Instead, changes are made to the data source that drives the Web site, and the Web site automatically adjusts to

reflect those changes. With a data-driven Web site, you connect to and present live data from a variety of data

sources.

Now the question is: how to do it?

2.2.2 Spaghetti a la Web

See document: Spaghetti_code

Many applications on the web today have a complex and tangled structure – just like spaghetti programs in the

1960s and 1970s.

Spaghetti code is a pejorative term for source code that has a complex and tangled control structure, especially

one using many gotos, exceptions, threads, global variables, or other "unstructured" constructs.

It is also used in pejorative sense to imply that a given piece of work is difficult to understand.

So, where can you find spaghetti on the Web apps?

Well, there are 3 primary scenarios:

1. Mixed code to the browser. Usually, HTML definitions, style sheets, and JavaScript code are not represented

separately. Rather, in most web sites, HTML definitions, style sheets and JavaScript functions are interspersed and

mixed in no specific order – other than the order that was established by the tools that were used to generate the

web page.

The source code of the web documents is not very easy to read and the actual behavior of the document is even

harder to understand.

Page 6: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

This is because the typical user interaction model of the web is such that a new web page is generated and sent to

the browser each time the user clicks on a link or a button on a page.

2. Creative freedom over software engineering. As long as the primary purpose of web development was the

creation of web sites consisting of documents, pages and forms, there was little reason

to apply established software engineering principles to web development. The web browser, with its original

design dating back to 1990, is quite well-suited to displaying documents and supporting simple navigation from

page to page.

3. Zero structure programming models. The old "spaghetti" code model of web developing platforms as ASP,

where actual code with application logic (VBScript, Jscript or whatever) was mixed with markup UI elements

(HTML) is a good example. Trying to maintain this applications today is really complicated because of a simple

question: where is it?

So, it seems that we need to ´put some order in here, but where to start?

2.2.3 Separate the code, please

See document: 112916.aspx

The most simple way to put some order to this mess is to separate. Let's put the put code in a separate script block

element and let the markup in the rest of the page.

Even when the organization unit is still the page, the page now have a structure.

Most often the ASP pages are HTML pages with embedded VBScript or JScript, but there is no problem to

implement ASP pages that generate plain text, XML or any other textual content. It is possible, of course, certain

ASP page to contain only script and no static non-script content at all.

This is especially useful when the application implements techniques such as page templates and all the content is

dynamically generated, or when the generated content is not textual.

So, to separate code from markup ASP provides:

* Script code in <% %> and <%= %> tags

* Script code in <SCRIPT RUNAT=SERVER ... > tags

* File include statement

* OBJECT RUNAT=SERVER tags

To separate code in a file with markup, script code tags are very useful.

But a better practice is to have a real separation of the code, so you can thing in terms of libraries; then you can

use a file include statement to consume them.

These are some ways to get some separation; however, execution can become messy because of the fact of

loading things that you maybe won´t use.

Are we done? Mmmm...No.

Page 7: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

2.2.4 ASP.Net: web forms & code behind

See document: what-is-asp-net.html

ASP.NET is a web application framework to allow programmers to build dynamic web sites, web applications and

web services.

In ASP.NET, Microsoft introduces the concept of a Web Form, much akin to a Windows Forms for Windows

programming. Using Web Forms, an ASP.NET developer can develop web applications by dragging and dropping

controls onto a design pane.

Believe me. There's a difference between imagine where the content is going to be, and actually see it on its place.

Another concept that Microsoft introduced in ASP.NET was the use of code behinds. Using code behinds, you can

have a clean separation of the UI code and the application logic.

In theory, this would allow a web designer, for example, to focus on the design markup with less potential for

disturbing the programming code that drives it.

2.2.5 Layered development

See document: QuickDocId.aspx

Layered development or multi-layer development refers to a development model where presentation, business

logic and data are separated.

The application, like a web site or a Windows Forms application is usually called the Presentation layer. Then in the

middle, you find the Business Logic Layer, or the BLL that is the bridge between the Presentation layer and the next

layer: the Data Access Layer or the DAL. This DAL then talks to the database to perform selects, inserts, updates

and deletes.

One of the ideas of this design is that you can replace one or more of the layers without affecting the others.

The design concept sounds good, but the problem is when it's time to code it. Many developers can argue that

they are doing a layered application, but they are writing all the logic in the code behind file of a form.

Maybe they'll try to separate the business and data layers, but everyone has different ideas and experiences about

doing this. Some people will try to get the data directly from the DB instead of creating a business object with that

responsibility.

So even when layers have a defined responsibility its necessary to restrict the way the application is actually coded.

And the only way to do that is applying a design that affects the code structure.

2.3 A little solar system

It's been stated that layering is not enough to achieve structure and behavior in our applications.

The programming model and language's flexibility let us code the way we want it. But in order to achieve code

reuse, better applications structure, its necessary to limit this freedom.

Page 8: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

One way to limit the way applications structure is by design, but the other one is by the programming model used

as the foundation to build the application.

For example, ASP.Net is a framework that forces us to use object orientation, and in the case of web forms, to

separate logic from presentation.

In this section the concepts of web application framework and design patterns is explored in order to create our

little solar system inside this ever growing universe called WWW.

2.3.1 The raise of web application frameworks

Web application frameworks are software tools that are commonly used to aid in the creation and management of

various types of online applications.

A web application framework can involve designing and launching pages for a website or provisioning various

applications to provide a wide range of web services to consumers.

The framework tends to include all the elements needed to accomplish the desired tasks, thus eliminating the

need to secure the necessary tools from different sources.

One of the key elements of any web application framework is the software library. As the name implies, software

libraries are a central repository for all types of software that may be utilized in the creation and ongoing function

of online activities.

A typical library will include software to help manage the creation and maintenance of online databases, provide

security to the web pages, and also help with mapping the pages so there is a sense of continuity and order.

2.3.2 The Model-View-Controller pattern

Model–view–controller (MVC) is an architectural pattern used in software engineering. Successful use of the

pattern isolates business logic from user interface considerations, resulting in an application where it is easier to

modify either the visual appearance of the application or the underlying business rules without affecting the other.

2.3.2.1 MVC components

The MVC pattern, separates an application in three components: Model, View and Controller:

Page 9: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

* Model: this is where all the business logic of the application resides: it can range from a simple static class that

returns a dataset to a complex multi-assembly Business Logic Layer that uses an assembly specific to the Data

Access Layer.

* View: at the other end of the application is the View, which displays the application's user interface and

contains the representation of the data that have been retrieved by the Model. This doesn't have logic, other than

the one strictly related to the presentation of data.

* Controller: between the two components stands the Controller. It acts as the orchestrator of all the

interactions among the other components and the users: it handles the requests, reads the form values, passes

them to the Model, decides which View to render and finally sends the data to be rendered to the View.

2.3.2.2 Basic control flow

See document: Model-view-controller

MVC is often seen in web applications, where the view is the actual HTML or XHTML page, and the controller is the

code that gathers dynamic data and generates the content within the HTML or XHTML. Finally, the model is

represented by the actual content, which is often stored in a database or in XML nodes, and the business rules that

transform that content based on user actions.

Though MVC comes in different flavors, control flow is generally as follows:

1. The user interacts with the user interface in some way (for example, presses a mouse button).

2. The controller handles the input event from the user interface, often via a registered handler or callback.

3. The controller notifies the model of the user action, possibly resulting in a change in the model's state. (for

example, the controller updates the user's shopping cart).[4]

4. A view uses the model indirectly to generate an appropriate user interface (for example, the view lists the

shopping cart's contents). The view gets its own data from the model. The model and controller have no direct

knowledge of the view.

5. The user interface waits for further user interactions, which restarts the cycle.

Page 10: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

2.3.2.3 MVC passive model

The passive model is employed when one controller manipulates the model exclusively. The controller modifies

the model and then informs the view that the model has changed and should be refreshed.

The model in this scenario is completely independent of the view and the controller, which means that there is no

means for the model to report changes in its state.

2.3.2.4 MVC active model

See document: ms978748.aspx

The active model is used when the model changes state without the controller's involvement. This can happen

when other sources are changing the data and the changes must be reflected in the views. Consider a stock-ticker

display. You receive stock data from an external source and want to update the views (for example, a ticker band

and an alert window) when the stock data changes. Because only the model detects changes to its internal state

when they occur, the model must notify the views to refresh the display.

However, one of the motivations of using the MVC pattern is to make the model independent from of the views. If

the model had to notify the views of changes, you would reintroduce the dependency you were looking to avoid.

Fortunately, the Observer pattern [Gamma95] provides a mechanism to alert other objects of state changes

without introducing dependencies on them.

2.3.2.5 Passive view: Model2

See document: PassiveScreen.html

This pattern is yet another variation on model-view-controller and model- view-presenter. As with these the UI is

split between a view that handles display and a controller that responds to user gestures.

The significant change with Passive View is that the view is made completely passive and is no longer responsible

for updating itself from the model. As a result all of the view logic is in the controller.

Page 11: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

As a result, there is no dependencies in either direction between the view and the model.

In a Model2 application, requests flow from the browser directly to the controller (via a HTTP handler). The user

interface of a Model2 application offers HTML input elements and all of them cause a link to be followed and a

HTTP post. On the Web server the request is captured and transformed into a method call on the selected

controller. As the controller’s method returns, the controller orders the view to render out to HTML. The view

receives fresh data for its response directly from the controller. The output of the view is delivered to the front

controller and sent back to the browser.

In Model2, we can really say that the controller is the entry point in the flow and the view is extremely thin and

passive—except for some JavaScript you may insert.

The driving reason to use Passive View is to enhance testability. With the view reduced to a dumb slave of the

controller, you run little risk by not testing the view. The controller can run and be tested outside of the UI

environment

2.3.3 The REST pattern

The Representational State Transfer (REST) style is an abstraction of the architectural elements within a distributed

hypermedia system. REST ignores the details of component implementation and protocol syntax in order to focus

on the roles of components, the constraints upon their interaction with other components, and their

interpretation of significant data elements.

It encompasses the fundamental constraints upon components, connectors, and data that define the basis of the

Web architecture, and thus the essence of its behavior as a network-based application.

REST is an architectural pattern that defines how network resources should be defined and addressed in order to

gain shorter response times, clear separation of concerns between the front-end and back- end of a networked

system. REST is based on three following principles:

* An application expresses its state and implements its functionality by acting on logical resources

* Each resource is addressed using a specific URL syntax

* All addressable resources feature a contracted set of operations

Page 12: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

2.4 What is ASP.NET MVC?

ASP.NET MVC is a framework that allows developers to apply the MVC pattern in the development of an ASP.NET

application, thus allowing a better separation of concerns, which results in better reusability and easier testing.

Now its easier to state that in this specific implementation of the MVC pattern the Passive View flavor is used: the

View is not responsible of updating itself but everything is performed by the Controller.

Like ASP.NET Web Forms, ASP.NET MVC is built on the ASP.NET framework.

2.4.1 ASP.MVC application's structure

See document: ASP.NET_MVC_Framework

ASP.Net MVC allows software developers to build a Web application as a composition of three roles: Model, View

and Controller.

A Model represents the state of a particular aspect of the application. Frequently, a model maps to a database

table with the entries in the table representing the state of the table.

A Controller handles interactions and updates the model to reflect a change in state of the application.

A View extracts necessary information from a model and renders a user interface to display that.

2.4.2 Contrasting ASP.NET and the MVC Framework

See document: AnArchitecturalViewOfTheASPNETMVCFramework.aspx

So here's an alternate way of looking at the MVC Framework. It is an ASP.NET framework that performs data

exchange by using a REST model versus the postback model of classic ASP.NET.

Page 13: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Each page is split into two distinct components -controller and view - that operate over the same model of data.

This is opposed to the classic code-behind model where no barrier is set that forces you to think in terms of

separation of concerns and controllers and views.

However, by keeping the code- behind class as thin as possible, and designing the business layer appropriately, a

good developer could achieve separation of concerns even without adopting MVC and its overhead.

MVC, however, is a model superior to a properly-done code-behind for its inherent support for test-driven

development.

2.4.3 Routes

See document: 10925_3788416_2

ASP.NET MVC applications handle the web requests thru controller classes, and the request from the browser is

directed to a particular controller via routes.

Routes are a new feature in .NET 3.5 SP1, and ASP.NET MVC uses this feature to give controller classes the

capability to respond to requests. ASP.NET MVC uses REST-like URLs (Representational State Transfer) that are

cleaner than regular ASP.NET web application URLs. Here are examples of such URLs:

/products/show/881

/customers/list

/login/register

As you can see, REST-like URLs tend to be clean, simple, and don't expose .aspx files directly on the server.

Although you can have directly addressed .aspx pages in ASP.NET MVC applications, this is not the main idea.

2.4.3.1 ASP.NET Routing

See document: tutorial-08-cs.aspx

The ASP.NET MVC framework depends on ASP.NET Routing to route browser requests to controller actions. In

order to take advantage of ASP.NET Routing, you might have to perform additional configuration steps on your

web server. It all depends on the version of Internet Information Services (IIS) and the request processing mode for

your application.

Here’s a summary of the different versions of IIS:

* IIS 7.0 (integrated mode) – No special configuration necessary to use ASP.NET Routing.

* IIS 7.0 (classic mode) – You need to perform special configuration to use ASP.NET Routing.

Page 14: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

* IIS 6.0 or below – You need to perform special configuration to use ASP.NET Routing.

2.5 ASP.Net inside

ASP.Net MVC is a proposal for the structural problem of web applications.

However, ASP.Net framework is the one that provides support to other important capabilities exploted in the new

framework.

The most important

2.5.1 Data access

If we want a data driven application, the fact is that we need to create a set of classes to represent (and access)

our database. And the alternatives are: do it your own way or use something that does it for you.

To access the database, you can choose one of the available options in the .Net framework:

+ ADO.NET’s classes. All that you need to connect to DBs, execute queries, read data or get a disconnected copy.

The control is in your hands, so you need to know how to use it. In fact, this all mighty power implies that you must

code all the data layer of your app. Just you, alone. So the question is: do you know how to do it?

+ Data source controls. The .NET framework offers five data source controls: SqlDataSource, AccessDataSource,

ObjectDataSource, XmlDataSource, and SiteMapDataSource; these objects enable automatic connection to various

data sources, and provide capabilities to read or modify your database using data-bound controls.

The problem with this alternative is that you need to attach these controls to each page where you need to use

data access, so there´s a strong cohesion issue.

Lucky you. In the last years MS has develop 2 new toys that create database models.

The LINQ to SQL and the MS Entity Framework.

2.5.1.1 LINQ to SQL

See document: using-linq-to-sql-part-1.aspx

Page 15: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

LINQ to SQL is an O/RM (object relational mapping) implementation that ships in the .NET Framework "Orcas"

release, and which allows you to model a relational database using .NET classes. You can then query the database

using LINQ, as well as update/insert/delete data from it.

LINQ to SQL fully supports transactions, views, and stored procedures. It also provides an easy way to integrate

data validation and business logic rules into your data model.

DataContext class

When you press the "save" button within the LINQ to SQL designer surface, Visual Studio will persist out .NET

classes that represent the entities and database relationships that we modeled. For each LINQ to SQL designer file

added to our solution, a custom DataContext class will also be generated.

This DataContext class is the main conduit by which we'll query entities from the database as well as apply

changes.

The DataContext class created will have properties that represent each Table we modeled within the database, as

well as methods for each Stored Procedure we added.

LINQ query syntax

See document: QueryExpressionSyntax.ashx

The query expression syntax is much gentler than the Expression Method syntax and simplifies writing LINQ

queries by removing Lambda Expressions and by using a familiar SQL like representation. One initial stumbling

block to learning the LINQ syntax is that it reverses the Select- From-Where SQL structure and introduces From-

Where-Select.

There is good reason for this switch in keyword ordering; it allows better intellisense support where Visual Studio

can offer assistance by displaying collection and properties whilst the developer is creating the query.

The basic form of the Query Expression is:

from [identifier] in [source collection]

let [expression]

where [boolean expression]

order by [[expression](ascending/descending)], [optionally repeat]

select [expression]

group [expression] by [expression] into [expression]

The queries return an IEnumerable<T>

Page 16: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

3 ASP.Net MVC: basic techniques

As anything in life, you must first walk before you run. Climbing the learning curve implies to take one step at a

time, so it´s important that steps are clear.

In this chapter, the goal is to explore the most common basic techniques to make small and precise things with

ASP.Net MVC.

Each technique will be a recipe and you can identify it because the name of each technique starts with a verb ;)

The best reason to do this, is to have a common set of imperative sentences that allow us to clearly follow a set of

instructions in order to make something more complex. But for that, first read this and then you can move on to

the next chapter.

3.1 Configure your development environment

The natural environment for ASP.Net MVC is MS Windows.

However, it is not the only playground where you can swing.

3.1.1 Windows environment

First, be patient. You'll need at least an hour to setup your dev environment.

The setup checklist includes the following:

+ Install on your machine Visual Studio 2008

+ Install Visual Studio 2008 Service Pack 1 (contains .Net framework 3.5 SP1)

+ Install ASP.NET MVC 1.0

http://www.microsoft.com/downloads/details.aspx?FamilyID=53289097-73ce- 43bf-b6a6-

35e00103cb4b&displaylang=en

Page 17: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

This is all that you need to start developing in your own machine.

3.1.2 Linux environment

According to some references, it is possible to do .Net development in Linux with Mono.

And it was a surprise that ASP.Net MVC was supported in Mono so fast.

The setup checklist includes the following:

- Mono SDK 2.4 (LINQ is expected to be integrated in version 2.6)

- MonoDevelopIDE 2.0

- ASP.Net MVC add-in for MonoDevelop.

That's all you need to work in a Linux environment.

3.2 Create an ASP.Net MVC application project See document: 3788416

Visual Studio's New Project dialog box should now have a new icon for "ASP.NET MVC Application"

Page 18: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

When you create a new ASP.NET MVC project, you will have several folders under the solution: namely Controllers,

Models, and Views. When you write code to implement your application, you should store each of the different

code files into their correct folders. Otherwise, the system might not work as designed.

3.3 The Models realm

3.3.1 Hard coded models

Page 19: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Before dealing with DBs and sophisticated DAL models and code generators, the most basic and easy way to make

models is by defining classes with as many properties as you may want or need.

This is a good exercise to understand how models work.

3.3.1.1 Create a model class

By using a model class, you can specify that a view should directly understand the properties of the model class;

this means you do not need to use the ViewData object nearly as often.

For instance, you might have a class like this to represent product information:

public class Product

{

public int Id { get; set; }

public string Name { get; set; }

public string Description { get; set; }

public float ListPrice { get; set; }

public float CostPrice { get; set; }

public string WebPage { get; set; }

public string SystemRequirements { get; set; }

}

The important thing here is to put this class on the Models folder.

3.3.2 The database

A relational database is a common persistence layer in software applications.

3.3.2.1 Create a database

To create a new database:

1. Right-click the App_Data folder in the Solution Explorer window and select the menu option Add, New Item.

2. Select the Data category and select the SQL Server Database template.

3. Name your new database <MyDBName>.mdf and click the Add button.

Page 20: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

After you create your database, you can connect to the database by double- clicking the .mdf file located in the

App_Data folder. Double-clicking the file opens the Server Explorer window.

Design the database on the fly

If your data model is crystal clear inside your head (ja-ja) or if you want to fool around with a couple of tables, then

you can use the Server explorer editing capabilities to create the tables and fields of your database.

Even you can populate your DB with data.

Page 21: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

This is a common practice when you try to remake an example from a tutorial or when you are working on a

prototype or when making your first steps in the database world.

Otherwise, if your system is complex enough (that is when relations between tables appear), maybe you need to

consider a specific tool for the job.

NOTE: remember to set the table primary key.

3.3.2.2 Design the DB model and create the database

3.3.2.3 Using an existing database

Lets suppose that you did a desktop application that you want to migrate to Web.

The database model is the same, so you want to use the actual database.

All that you need to do is copy the DB file to your project (assuming you are using Access or SQL Server, attach the

DB, and you are done.

3.3.3 The database model classes

In several seminars, tutorials and samples, there are 2 technologies preferred when you have to create the DB

model classes:

+ LINQ to SQL

+ MS Entity Framework

Their advantage is that generate the DB model is very easy and straight forward.

To let everyone choose its favorite, I'll try of maintain a description for each technology.

3.3.3.1 LINQ to SQL style

Create a MVC data model

In LINQ to SQL, the object relational designer analyzes a SQL Server database and presents the data tables and

stored procedures to code as objects.

1. Add a LINQ to SQL Classes file <MyDataClasses>.dbml to the project (File->New File->LINQ to SQL Classes-

>Add).

Page 22: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Create Entity Classes From a Database

If you already have a database schema defined, you can use it to quickly create LINQ to SQL entity classes modeled

off of it.

The easiest way to accomplish this is to open up a database in the Server Explorer within Visual Studio, select the

Tables and Views you want to model in it, and drag/drop them onto the LINQ to SQL designer surface.

1. From Server Explorer, expand the Tables node.

2. Drag table names from the Server Explorer and drop them on the left- hand (larger) design surface.

The designer creates objects based on the table names.

Page 23: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

3.3.3.2 Entity Framework style

Create a MVC data model

See document: tutorial-26-cs.aspx

Microsoft Entity Framework to generate the classes for our database model automatically.

1. Right-click the Models folder in the Solution Explorer window and the select the menu option Add, New Item.

2. Select the Data category and select the ADO.NET Entity Data Model template.

3. Give your data model the name <MyDBModel>.edmx and click the Add button.

The Entity Data Model Wizard appears.

Generate model from DB

In the Entity data model wizard:

1. In the Choose Model Contents step, select the Generate from database option.

2. In the Choose Your Data Connection step, use the <MyDB>.mdf data connection and the name <MyDBEntities>

for the connection settings. Click Next.

Page 24: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

3. In the Choose Your Database Objects step, mark the Tables node to select all the tables or expand the node,

and select the tables you need. Enter the namespace Models and click the Finish button.

After you complete the Entity Data Model Wizard, the Entity Data Model Designer appears. The designer displays a

class that corresponds to each table being modeled.

Page 25: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

The Entity Data Model wizard generates class names based on database table names. You almost always need to

change the name of the class generated by the wizard. Change the name of the class from (plural) to (singular).

3.4 The Controllers realm

3.4.1 Controller class and actions

A controller class is a lot lighter weight than a page. As a matter of fact, the only things that are truly necessary are

to derive from System.Web.Mvc.Controller.

An action is a method that's called in response to a request to a particular URL. Actions are responsible for doing

whatever processing is required and then rendering a view.

3.4.1.1 Create a MVC Controller

To create a new ASP.NET MVC Controller:

+ Select the menu option Add, Controller.

+ In the Add Controller dialog, enter the name. Remember, this has to end in Controller as there are some

conventions we use to find these types.

+ Check the checkbox labeled Add action methods for Create, Update, and Details scenarios

+ Click add to create the new controller.

When add action methods for CRUD is selected, several method stubs are defined in the controller class (index,

details, create and edit).

Page 26: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

If this option is not selected, only the index action method stub will be generated.

3.4.1.2 Define an action method

MVC framework that enables us to define "action methods" on our controller, and then have the Controller base

class automatically invoke the appropriate action method to execute based on the URL routing rules in use for our

application.

To define a new action:

+ Define a new public method that returns an ActionResult.

+ Name the method

In earlier versions, it was needed to put the [ControllerAction] attribute on your action methods, but that is now

deprecated.

3.4.1.3 Specify the model object instance in the controller

To specify the model object instance in the controller, you would modify the return statement slightly:

Models.Product product = new Models.Product();

product.Id = 123;

// ...

return View(product);

3.4.2 ViewData

The controller often needs to specify what data to display on the view, such as choosing the correct product. To

better enable this communication between the view and the controller, the ASP.NET MVC framework contains a

class called ViewData.

This is a dictionary of name and value pairs, and it is accessible from both the controller class and the view's .aspx

page.

3.4.2.1 Define a controller's action to pass data

See document: 10925_3788416_4

public ActionResult Index()

Page 27: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

{

ViewData["Title"] = "Home Page";

ViewData["Message"] = "Welcome to ASP.NET MVC!";

return View();

}

The Index method uses the ViewData object two times, to set a "Title" and a "Message". Because the ViewData is a

collection object, you can freely choose any unique string value you prefer. The third statement in the method

returns a View object.

3.4.3 CRUD

The acronym CRUD refers to all of the major functions that need to be implemented in a relational database

application to consider it complete.

Each letter in the acronym can be mapped to a standard SQL statement:

Operation SQL

Create INSERT

Read (Retrieve) SELECT

Update UPDATE

Delete (Destroy) DELETE

Although a relational database is a common persistence layer in software applications, there are numerous others.

CRUD can be implemented with an object database, an XML database, flat text files, custom file format.

3.4.4 CRUD controller (LINQ to SQL style)

One of the most common things that you will want to do is to get data from the models you create.

Maybe you want to get all the registers from a table, or just a few. Maybe you need to insert new records or edit

and update some existing or maybe you want to delete some.

Create, read, update and delete (CRUD) are the four basic functions of persistent storage, a major part of nearly all

computer software.

With the model created, you will need the actions needed to specify how this operations do their job.

Page 28: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

In this section is shown how to define action methods consuming a LINQ to SQL model.

3.4.4.1 Create an instance of the model database context

- Add a reference to the models

using MyMvcApplication.Models

Create a class member variable of type DataContext in the controller. We will use this context to access the

database.

private MoviesDataClassesDataContext dbcontext = new

MoviesDataClassesDataContext();

3.4.4.2 Define an action to get the list of items from the database

See document: article.aspx

- Define a new controller action method (you can add this in Index method or make a List method) and inside of it:

- Define a LINQ query:

* The var keyword tells the compiler to infer the type returned by a query. When a LINQ to Objects query is

deferred, the sequence returned from a query expression is of type IEnumerable<T> and is called a computation or

result sequence.

* The individual lines in a properly formatted query are called clauses.

* The select clause at the end of the query helps define the type returned of the query. A select clause is said to

project a result.

// GET: /Movies/

public ActionResult Index()

{

var list = from item in dbcontext.Movies orderby item.Title select item;

return View(list.ToList());

}

3.4.4.3 Define an action to display details from a specific item

- Define a new controller action method or use the Details action method stub and inside of it:

- Define a LINQ query that retrieves the item that match with the primary key value. For this, use the Single

method of the context object, and state the condition to match.

Page 29: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

// GET: /Movies/Details/5

public ActionResult Details(int id)

{

Movie movie= dbcontext.Movies.Single(m=>m.ID ==id );

return View(movie);

}

The action method parameter must match the field type in the context model.

3.4.4.4 Define actions to edit an item

See document: create-a-strongly-typed-crud-ui-with-asp-net-mvc-rc.aspx

Notice that the controller has 2 overloads of the Edit action:

// GET: /Vehicles/Edit/5

public ActionResult Edit(int id)

{

...

}

// POST: /Vehicles/Edit/5

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Edit(int id, FormCollection collection)

{

...

}

The first one is for getting the item details in order to display then in the View. When the user clicks the submit

button, a POST message will call the second overload with the form data.

Get the details of the item to display

This implementation is identical to the Display action implementation.

// GET: /Movies/Edit/5

public ActionResult Edit(int id)

{

Movie movieToEdit = dbcontext.Movies.Single(m => m.ID == id);

return View(movieToEdit);

Page 30: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

}

Define save action

In the second overload of the Edit method, get the data out of the FormCollection instance, and apply it the item.

Then save the changes to the DB, and display the list.

// POST: /Movies/Edit/5

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Edit(int id, FormCollection collection)

{

//get the movie to save

Movie movie = dbcontext.Movies.Single(m => m.ID == id);

try

{

// Assign the new values

movie.Title = collection ["Title"];

movie.Website = collection["Website"];

// Save changes context.SubmitChanges();

return RedirectToAction("Index");

}

catch

{

return View(movie);

}

}

3.4.4.5 Define actions to create a new item

See document: create-a-strongly-typed-crud-ui-with-asp-net-mvc-rc.aspx

Create method has 2 overloads as well.

Again, one is to do any work before the Create View is shown and the other is to respond to the POST message and

insert the data to the database.

Page 31: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

To Implement the second overload of the Create method, extract the data from the FormCollection instance, and

build a new instance of Vehicle. Then, add it to the database, and return to the list.

// GET: /Movies/Create

public ActionResult Create()

{

return View();

}

// POST: /Movies/Create

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Create(FormCollection collection)

{

try

{

Movie v = new Movie

{

Title = collection["Title"],

Website = collection["Website"],

};

context.Movies.InsertOnSubmit(v); context.SubmitChanges();

return RedirectToAction("Index");

}

catch

{

return View();

}

}

3.4.4.6 Error in edit and create operations

It's important to check if the tables of your data models have primary keys defined. Otherwise, edit and create

operations can´t be performed.

If you forgot to set the table primary key, you will have to copy the table to the LINQ designer in order to set the

changes.

The actual error is:

Page 32: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

{"Can't perform Create, Update or Delete operations on 'Table(Movie)' because it has no primary key."}

If you don´t implement error handling, you can notice the error because no new records or changes are applied to

the DB.

However is a good idea to see how to implement error handling in controllers.

3.4.5 CRUD controller (Entity framework style)

See document: tutorial-26-cs.aspx

Now that we know how to define action methods and use the LINQ to SQL, I think that is important to explore the

use of Entity framework for 2 reasons:

+ Comparison. If you want to know which is better or fits better to your requirements or coding style.

+ Coding differences. There are slightly differences between both models, so its important to be aware of them.

In this section I expose the same techniques for CRUD operations, so you can have the best of both worlds.

3.4.5.1 Create an instance of the data model

- Add a reference to the models

using MyMvcApplication.Models

Define a class member variable of the type you define when the model was generated (with suffix Entities)

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Mvc.Ajax;

using MvcAgenda.Models;

namespace MvcAgenda.Controllers

{

public class ContactsController : Controller

{

ContactsDBEntities dbentities = new ContactsDBEntities();

Page 33: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

We will use this context to access the database.

3.4.5.2 Define an action to list items from the DB

- Define a new controller action method (you can add this in Index method or make a List method)

- Inside of the method, in the parenthesis of the View(), add a call to the data model entities to return a set of

items and convert them to a list.

ContactsDBEntities dbentities = new ContactsDBEntities();

// GET: /Contacts/

public ActionResult Index()

{

return View(dbentities.ContactSet.ToList () );

}

Its interesting to note that entities has an ItemSet ready to consume.

3.4.5.3 Define an action to create a new item

To enable users to create new items, we need to add two Create() actions to the controller. We need to create one

Create() action that returns an HTML form for creating a new item. We need to create a second Create() action

that performs the actual database insert of the new item.

In the second Create method:

- Modify entry parameter to accept an instance of the Item class.

- Decorate parameter with a [Bind] attribute. The [Bind] attribute is used to exclude the Id property from binding.

Because the Id property represents an Identity property, we don’t want to set the Id property.

- Add a new Item to the existing set of Contacts and call the SaveChanges() method to push these changes back to

the underlying database.

// POST: /Contacts/Create

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Create([Bind(Exclude ="Id")]Contact contacto)

{

if(!ModelState.IsValid)

return View();

Page 34: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

try

{

// add the item to the items set and save

dbentities.AddToContactSet(contacto);

dbentities.SaveChanges();

return RedirectToAction("Index");

}

catch

{

return View();

}

}

Shortcut discovery: You can generate an HTML form for creating new Contacts by right-clicking either of the two

Create() methods and selecting the menu option Add View

3.4.5.4 Define an action to display details from a specific item

- Define a new controller action method or use the Details action method stub and inside of it:

- Define a variable and assign it the result of a LINQ query that retrieves the item that match with the primary key

value.

- Pass the variable to the View.

// GET: /Contacts/Details/5

public ActionResult Details(int id)

{

var item = (from c in dbentities.ContactSet where (c.ID == id)

select c).FirstOrDefault();

return View(item);

}

3.4.5.5 Define actions to edit an item

The first Edit() method is invoked by an HTTP GET operation. An Id parameter is passed to this method which

represents the Id of the contact record being edited. The Entity Framework is used to retrieve a contact that

matches the Id. A view that contains an HTML form for editing a record is returned.

Page 35: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

The second Edit() method performs the actual update to the database. This method accepts an instance of the

Contact class as a parameter. The ASP.NET MVC framework binds the form fields from the Edit form to this class

automatically. Notice that you don’t include the*Bind+ attribute when editing a Contact (we need the value of the

Id property).

The Entity Framework is used to save the modified Contact to the database. The original Contact must be retrieved

from the database first. Next, the Entity Framework ApplyPropertyChanges() method is called to record the

changes to the Contact. Finally, the Entity Framework SaveChanges() method is called to persist the changes to the

underlying database.

// GET: /Contacts/Edit/5

public ActionResult Edit(int id)

{

var contact2Edit = (from c in dbentities.ContactSet where(c.ID ==

id)select c).FirstOrDefault();

return View(contact2Edit);

}

//

// POST: /Contacts/Edit/5

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Edit(Contact contact2Edit)

{

if(!ModelState.IsValid)

return View();

try

{

// Get the original item, apply the changes and save it

var originalContact = (from c in dbentities.ContactSet

where(c.ID == contact2Edit.ID ) select c).FirstOrDefault();

dbentities.ApplyPropertyChanges(originalContact.EntityKey.EntitySetName,

contact2Edit);

dbentities.SaveChanges();

return RedirectToAction("Index");

}

Page 36: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

catch

{

return View();

}

}

3.4.5.6 Define an action to delete an item

If you want to delete contacts then you need to add two Delete() actions to the controller class. The first Delete()

action displays a delete confirmation form. The second Delete() action performs the actual delete.

The first Delete() method returns a confirmation form for deleting a record from the database.

The second Delete() method performs the actual delete operation against the database.

After the original item has been retrieved from the database, the Entity Framework DeleteObject() and

SaveChanges() methods are called to perform the database delete.

//

// GET: /Home/Delete/5

public ActionResult Delete(int id)

{

var contactToDelete = (from c in dbentities.ContactSet

wherec.ID == id

select c).FirstOrDefault();

return View(contactToDelete);

}

// POST: /Home/Delete/5

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Delete(Contact contactToDelete)

{

try

{

var originalContact = (from c in dbentities.ContactSet

where c.ID == contactToDelete.ID

select c).FirstOrDefault();

dbentities.DeleteObject(originalContact);

dbentities.SaveChanges();

return RedirectToAction("Index");

}

Page 37: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

catch

{

return View();

}

}

3.5 The Views realm

3.5.1 New views for controllers

See document: cc337884.aspx

3.5.1.1 The /Views Directory Structure

See document: asp-net-mvc-framework-part-1.aspx

By default when you create a new ASP.NET MVC Project using Visual Studio, it will create a "Shared" sub-directory

underneath the "Views" directory root. This is the recommended place to store Master Pages, User Controls, and

Views that we want to share across multiple Controllers within the application.

When building views that are specific to an individual controller, the default ASP.NET MVC convention is to store

them in sub-directories under the \Views root. By default the name of a sub- directory should correspond to the

Controller name. For example, if the Controller class is called "ProductsController", we will by default store the

Views specific to it within the \Views\Products sub- directory.

When we call the View(string viewName) method within a specific Controller, the MVC framework will

automatically first look for a corresponding .aspx or .ascx view template underneath the \Views\ControllerName

directory, and then if it can't find an appropriate view template there it will check the \Views\Shared directory for

one

3.5.1.2 Create a new folder with controller's prefix name

To do this, first create a new folder in the solution under the Views folder.

By default, the controller will look for a view in the Views\<ControllerPrefix> folder (the controller prefix is the

name of the controller class minus the word "Controller").

So if your controller's name is HelloController, the new folder's name will be Hello.

Page 38: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

3.5.1.3 Create a view

Inside the new folder create a new view.

The name of the ASPX file must match the name of one of the methods of the controller (for example, Index).

Note that MVC views are only responsible for generating output, so they don't need any of the event handling or

complex controls that Web Forms pages do.

The MVC Framework does borrow the .aspx file format as a useful text templating language.

3.5.2 CRUD views

See document: Create,_read,_update_and_delete

CRUD is also relevant at the user interface level of most applications. For example, in address book software, the

basic storage unit is an individual contact entry.

As a bare minimum, the software must allow the user to:

* Create or add new entries

* Read, retrieve, search, or view existing entries

* Update or edit existing entries

* Delete existing entries

Without at least these four operations, the software cannot be considered complete. Because these operations are

so fundamental, they are often documented and described under one comprehensive heading, such as "contact

management" or "contact maintenance" (or "document management" in general, depending on the basic storage

unit for the particular application).

The following techniques show how to generate views using the Add View wizard. With this, new pages are

created with all the fields required to match de DB model.

3.5.2.1 Create a view to list items

Inside the Views folder, in the folder that match the desired controller:

- Right click the folder and select Add/View

Page 39: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

- Write the name for the new View

- Select the create a strong-typed view option

- select the view data class MyMVCApp.Models.MyDB

- Select the view content option as List

- Select the site's master page.

- Click the Add button.

This will generate a new aspx page with all the fields returned by the DB model, to be displayed on a table.

3.5.2.2 Create a view to display item details

Inside the Views folder, in the folder that match the desired controller:

- Right click the folder and select Add/View

- Write the name for the new View

- Select the create a strong-typed view option

- select the view data class MyMVCApp.Models.MyDB

- Select the view content option as Details

- Select the site's master page.

- Click the Add button.

This will generate a new aspx page with all the fields returned by the DB model, to show the detail of one item.

This page can be accessed from the list page, that has a Detail option. All you have to do is un comment the id

reference in the Details action link, and adjust the proper primary key field name.

<%=Html.ActionLink("Details", "Details", new{ id=item.ID })%>

NOTE: When using Entity framework, this changes are not necessary.

3.5.2.3 Create a view to edit item

The Edit() action return an HTML form that can be used to edit a DB record.

Inside the Views folder, in the folder that match the desired controller:

- Right click the folder and select Add/View

- Write the name for the new View

- Select the create a strong-typed view option

Page 40: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

- select the view data class MyMVCApp.Models.MyDB

- Select the view content option as Details

- Select the site's master page.

- Click the Add button.

This will generate a new aspx page with all the fields returned by the DB model, to show the detail of one item.

This page can be accessed from the list page, that has a Detail option. All you have to do is un comment the id

reference in the Edit action link, and adjust the proper primary key field name.

<%= Html.ActionLink("Edit", "Edit", new { id=item.ID }) %> |

Edit page can be access too from the details page. All you have to do is un comment the id reference in the Edit

action link, and adjust the proper primary key field name.

<%=Html.ActionLink("Edit", "Edit", new { id=Model.ID }) %> |

3.5.2.4 Create a view to create a new item

Inside the Views folder, in the folder that match the desired controller:

- Right click the folder and select Add/View

- Write the name for the new View (Create)

- Select the create a strong-typed view option

- select the view data class MyMVCApp.Models.MyDB

- Select the view content option as Create

- Select the site's master page.

- Click the Add button.

This will generate a new aspx page with all the fields needed by the DB model, to define a new item.

This page can be accessed from the list page, that has a Create new option.

3.5.2.5 Create a view to delete an item

Modify the Index view so that it contains a link for deleting contact records . You need to add the following code to

the same table cell that contains the Edit link:

Html.ActionLink( { id=item.Id }) %>

Page 41: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Create the delete confirmation view. Right-click the Delete() method in the controller class and select the menu

option Add View. The Add View dialog appears.

Unlike in the case of the List, Create, and Edit views, the Add View dialog does not contain an option to create a

Delete view. Instead, select the ContactManager.Models.Contact data class and the Empty view content. Selecting

the Empty view content option will require us to create the view ourselves.

This view contains a form that confirms whether or not a particular contact should be deleted

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.Contact>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">

<title>Delete</title>

</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Delete</h2>

<p>

Are you sure that you want to delete the entry for

<%= Model.Name %> ?

</p>

<% using (Html.BeginForm(new { Id = Model.ID }))

{ %>

<p>

<input type="submit" value="Delete" />

</p>

<% } %>

<div>

<%=Html.ActionLink("Back to List", "Index") %>

</div>

</asp:Content>

3.5.3 Control your views, Luke

Page 42: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Yeah, I know. Wizards are nice way to get the work done, but a certain thing is that there are not wizards for every

situation.

If you want full control of your UI, then you must know how to deal with this in ASP.Net MVC.

3.5.3.1 The view header

Ok, so you create a view. What´s inside it?

At the top of each aspx page, there´s a header tag to identify the views.

<%@Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

Inherits="System.Web.Mvc.ViewPage"%>

Each @Page tag has the following properties:

a. Page title

b. Language used in the page logic.

c. The masterpage used for the look and feel of the page.

d. An Inherits property to specify that this page derives from the ViewPage MVC framework.

This last property is very interesting. The views wizard adds some information here to specify the object types that

are passed to the view.

Examples:

1. A header where is specified a Comment model is passed to the view.

<%@Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

Inherits="System.Web.Mvc.ViewPage<IEnumerable<MvcBlog.Models.Comment>>"%>

2. A manually defined FileInfo objects list.

<%@Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

Inherits="System.Web.Mvc.ViewPage<List<System.IO.FileInfo>>"%>

3. A header specifying an error handling object.

<%@Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>"%>

To know this is very useful if not working with wizards or want to make manual changes.

3.5.3.2 HTML rendering

The most common use of view is to render HTML content that decorates your data for the output.

Page 43: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

As with ASP.Net, you still have the support for using master pages to define the site pages layout, and then you can

add the specific content to each page of your site using plain HTML and other tools.

Master and Content Pages

See document: default.aspx

Defining a Master Page is just like defining a normal page. Master Pages can contain markup, controls, or code, or

any combination of these elements. However, a Master Page can contain a special type of control, called a

ContentPlaceHolder control.

A ContentPlaceHolder defines a region of the master page rendering that can be substituted with content from a

page that derives from the master. A ContentPlaceHolder can also contain default content, just in case the derive

page does not need to override this content.

<%-- ContentPlaceHolder control --%>

<asp:contentplaceholder id="FlowerText" runat="server"/>

To differentiate a Master Page from a normal page, a Master Page is saved under the .master file extension. A

page can derive from a Master Page by defining a MasterPageFile attribute on its Page directive.

<%@ Page MasterPageFile="Site.master" %>

A Content Page can declare Content controls that specifically override content placeholder sections in the Master

Page. A Content control is associated to a particular ContentPlaceHolder control through its ContentPlaceHolderID

property. A Content Page may only contain markup and controls inside Content controls; it cannot have any top-

level content of its own. It can, however, have directives or code.

<%@ Page MasterPageFile="Site.master" %>

<asp:content id="Content1" contentplaceholderid="myText" runat="server">

First content area for the TITLE.

</asp:content>

<asp:content id="Content2" contentplaceholderid="myPicture" runat="server">

<asp:Image id="image1" imageurl="~/images/smiley.jpg" runat="server"/>

</asp:content>

Raw HTML tags

Page 44: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Inside content area, the most basic rendering can be made with raw HTML tags.

Remember <h2></h2>, <p></p>, <br/>, <table></table> and so on.

HTML helpers

See document: dd410596.aspx

An HTML Helper, typically, is a method that generates a string. You can use HTML Helpers to generate standard

HTML elements such as textboxes, links, dropdown lists, and list boxes.

TextBox

Extension method: <%= Html.TextBox(“name”) %>

Html output: <input id=”name” name=”name” type=”text” value=”" />

CheckBox

Extension method: <%= Html.CheckBox(“active”) %>

Html output: <input id=”active” name=”active” type=”checkbox” value=”false” />

MVC introduces HTML Helpers that take the place of Server Controls and help you build out your HTML.

The ASP.NET MVC framework includes helper methods that provide an easy way to render HTML in a view.

The following list shows some of the currently available HTML helpers. The helpers listed with an asterisk (*) are

demonstrated in this topic.

ActionLink — Links to an action method.

BeginForm — Marks the start of a form and links to the action method that renders the form.

CheckBox — Renders a check box.

DropDownList —Renders a drop-down list.

Hidden — Embeds information in the form that is not rendered for the user to see.

ListBox — Renders a list box.

Password — Renders a text box for entering a password.

RadioButton — Renders a radio button.

TextArea — Renders a text area (multi-line text box).

TextBox — Renders a text box.

Page 45: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

BeginForm Helper

The BeginForm helper marks the start of an HTML form and renders as an HTML form element. The BeginForm

helper method has several overrides.

The BeginForm helper implements the IDisposable interface, which enables you to use the using keyword (Using

in Visual Basic), similar to ASP.NET AJAX usage.

<% using(Html.BeginForm("HandleForm", "Home")) %>

<% { %>

<!-- Form content goes here -->

<% } %>

RadioButton helper

The RadioButton helper method renders a radio button. In its simplest form, the method takes three parameters:

the name of the control group, the option value, and a Boolean value that determines whether the radio button is

selected initially.

Select your favorite color:<br />

<%= Html.RadioButton("favColor", "Blue", true) %> Blue <br />

<%= Html.RadioButton("favColor", "Purple", false)%> Purple <br />

<%= Html.RadioButton("favColor", "Red", false)%> Red <br />

<%= Html.RadioButton("favColor", "Orange", false)%> Orange <br />

TextBox helper

The TextBox helper method renders a text box that has the specified name.

Enter your name: <%= Html.TextBox("name") %>

Html.ActionLink

See document: chapter-6-understanding-html-helpers.aspx

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

%>

Page 46: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

<p>

To learn more about this website, click the following link:

<%= Html.ActionLink("About this Website", "About" ) %>

</p>

</asp:Content>

In Listing, the first parameter passed to the Html.ActionLink() represents the link text and the second parameter

represents the name of the controller action. This Html.ActionLink() helper renders the following HTML:

<a href="/Home/About">About this Website</a>

The Html.ActionLink() helper has several overloads and supports several parameters:

· linkText – The label for the link.

· actionName – The action that is the target of the link.

· routeValues – The set of values passed to the action.

· controllerName – The controller that is the target of the link.

· htmlAttributes – The set of HTML attributes to add to the link.

· protocol – The protocol for the link (for example, https)

· hostname – The host name for the link (for example, www.MyWebsite.com)

· fragment – The fragment (anchor target) for the link. For example, to link to a div in a view with an id of news,

you would specify news for the fragment.

Notice that you can pass route values from an Html.ActionLink() to a controller action. For example, you might

need to pass the Id of a database record that you want to edit. Here’s how you pass an Id parameter to the Edit()

action:

[C#]

<%= Html.ActionLink("Edit Record", "Edit", new {Id=3})

[VB]

<%= Html.ActionLink("Edit Record", "Edit", New With {.Id=3})%>

Html.Encode

See document: html-escaping-in-aspnet-mvc.html

HtmlEncode is only meant to encode characters for display in HTML. It specifically does not encode whitespace

characters.

HTML escaping is a key part of web site security, mainly to prevent Cross-Site Scripting (XSS) attacks. I’m no

security expert, but I do know that everything the user types in must be HTML escaped before rendering it in the

browser, otherwise bad people could do nasty things like write javascript which steals all the users cookies.

Page 47: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

HTML escaping isn’t hard to do. You just convert < into &lt; and a few other conversions. .NET provides a very

simple way to do it:

view plaincopy to clipboardprint?

1. var encodedContent = HttpUtility.HtmlEncode(userEnteredContent);

var encodedContent = HttpUtility.HtmlEncode(userEnteredContent);

ASP.NET MVC makes it pretty easy too:

<p>

<%= Html.Encode(ViewData.Model.UserEnteredContent) %>

</p>

But the tricky bit is remembering to do it every single time. If we forget in once place in the whole app, we’ve

introduced a security hole.

ValidationSummary and ValidationMessage

See document: dd410404.aspx

Validating user input to make sure that it matches the data model in an ASP.NET MVC application can help you

protect the application data from user input mistakes and from users who have malicious intent. There are many

ways to incorporate input validation in an MVC application.

At the top of the view, the ValidationSummary helper method renders a list of validation errors, if any are found.

In addition, the ValidationMessage helper method renders a validation error message next to each form field for

which an error is found.

<h2>Create</h2>

<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>

<% using (Html.BeginForm()) {%>

<fieldset>

<legend>Fields</legend>

<p>

<label for="Name">Name:</label>

<%= Html.TextBox("Name") %> Required

<%= Html.ValidationMessage("Name", "*") %>

Page 48: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

</p>

<p>

<label for="Age">Age:</label>

<%= Html.TextBox("Age") %> Required

<%= Html.ValidationMessage("Age", "*") %>

</p>

<p>

<label for="Street">Street:</label>

<%= Html.TextBox("Street") %>

<%= Html.ValidationMessage("Street", "*") %>

</p>

<p>

<label for="City">City:</label>

<%= Html.TextBox("City") %>

<%= Html.ValidationMessage("City", "*") %>

</p>

<p>

<label for="State">State:</label>

<%= Html.TextBox("State") %>

<%= Html.ValidationMessage("State", "*") %>

</p>

<p>

<label for="Zipcode">Zipcode:</label>

<%= Html.TextBox("Zipcode") %>

<%= Html.ValidationMessage("Zipcode", "*") %>

</p>

<p>

<label for="Phone">Phone:</label>

<%= Html.TextBox("Phone") %> Required

<%= Html.ValidationMessage("Phone", "*") %>

</p>

<p>

<label for="Email">Email:</label>

Page 49: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

<%= Html.TextBox("Email") %> Required

<%= Html.ValidationMessage("Email", "*") %>

</p>

<p>

<input type="submit" value="Create" />

</p>

</fieldset>

<% } %>

<div>

<%=Html.ActionLink("Back to List", "Index") %>

</div>

Create custom Html helper method

See document: HtmlHelperMethod.aspx

Custom Html Helper method could we created in two ways

1.

Using static method.

2.

By extension method.

static method

The easiest way to create custom Html helper method is create static method and return a string. Here we are

going to create a Html helper method, which will render a label element of Html.

Step 1:

Add a new folder called Helpers in Asp.Net MVC application.

Step 2:

Page 50: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Add a class in newly created Helpers folder. Right click at folder and then add class named LableHelper.cs

Step 3:

Now add static method in this class called Label. This method will return string and will take two string parameters

named target and text.

Code will be like below

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace MvcApplication2.Helpers

{

public class LabelHelper

{

public static string Label(string target, string text)

{

return String.Format("<label for= '{0}'>{1}</label>",target,text);

}

}

}

Step 4:

Now, we are going to use Label Html helper in view or aspx page.

View\Home\Index.aspx

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

%>

<%@ Import Namespace="MvcApplication2.Helpers" %>

Page 51: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

<asp:Content ID="indexHead" ContentPlaceHolderID="head" runat="server">

<title>Home Page</title>

</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

<h2><%= Html.Encode(ViewData["Message"]) %></h2>

<p>

To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC

Website">http://asp.net/mvc</a>.

</p>

<div>

<%using(Html.BeginForm())

{ %>

<%=LabelHelper.Label("firstName","Firstname") %>

<% } %>

</div>

</asp:Content>

In above code couples of things are worth noticing.

1. We have included Namespace for Html Handler method of Label.

2. Html.BeginForm is inside using , such that after rendering form will get closed.

3. LabelHelper.Label is preceded by <%=.

Extension method

public static class LabelExtensions

{

public static string Label(this HtmlHelper helper, string target, string text)

{

return String.Format("<label for='{0}'>{1}</label>", target, text);

Page 52: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

}

}

In above code fact noticing are

1. First parameter to Html Helper method is this . In case of extension method always first parameter is class

on which we are extending the method.

2. Extended method enables us to add new method in existing class.

3. Here class is static class. We must define Extension method with static class.

4. Extension method will be read be Intellisense like other method of the class.

3.5.3.3 Partial Views

See document: dd942822.aspx

Another technique you can use to manage the complexity of views is partial views. Partial views in the Web forms

view engine are user control files with a .ascx extension. Just like in ASP.NET Web forms, we can use partial views

to encapsulate HTML and code that we might want to reuse across multiple views (like a login display). We can

also use partials to break down a complicated view into smaller pieces.

We can strongly type partial views by deriving from System.Web.Mvc.ViewUserControl<T>. The add new view

wizard in an MVC application allows you to select a checkbox to choose between a view and a partial view, and

also allows you to select the strongly typed model. There is also an HTML helper available (RenderPartial) in the

framework to make the job of using a partial view easy:

<% Html.RenderPartial("_LoginStatus"); %>

Render partial helper

See document: tip-of-the-day-185-aspnet-mvc-html-helpers

Render Partial: Used to render partial views (ascx controls)

* void RenderPartial(this HtmlHelper htmlHelper, string partialViewName);

* void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model);

* void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData);

* void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary

viewData);

3.5.3.4 Views can incarnate in other formats

See document: asp-net-mvc-view-more-just-a-page-view-part-i.aspx

Page 53: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

At this point, anyone could say "views are HTML", but this is not necessarily true.

Views can adopt other formats, so a view could be a XML.

For example, suppose you need to expose an RSS

Because it´s a MVC view, the file must have a header, as any other MVC view. The main difference is the XML

header added. From this point you can specify you XML structure, and consume your model's data as usual,

making the apropiate calls inside script tags (<% %>, <%= %>).

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<WebSite.Models.RssFeed>" %><?xml

version="1.0" encoding="utf-8" ?>

<rss version="2.0">

<channel>

<title><%= Model.Title %></title>

<link><%= Model.Link %></link>

<ttl>10</ttl>

<pubDate><%= Model.PubDateString %></pubDate>

<lastBuildDate><%= Model.LastBuildDateString %></lastBuildDate>

<description><![CDATA[

<%= Model.Description %>

]]></description>

<% foreach (var item in Model.Items) { %>

<item>

<title><%= item.Title %></title>

<link><%= item.Link %></link>

<guid><%= item.Link %></guid>

<pubDate><%= item.PubDateString %></pubDate>

<description><![CDATA[

<%= item.Description %>

]]></description>

</item>

<% } %>

</channel>

</rss>

Page 54: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

4 ASP.Net MVC: basic code katas

The word Kata comes from the Japanese meaning formal exercise. In martial arts, a kata is a series of movements

and techniques that are practiced in a pattern. Each kata is designed to teach a central principle or a set of

common technique.

These defensive and offensive movements will serve you to response to one or more attackers (imaginary or real

clients, or just you and a crazy idea).

In this chapter, the goal is to define and code some simple apps, to show how to apply the basic techniques

discussed previously.

The examples are designed to integrate the basic techniques to solve common development scenarios.

These basic katas can be resumed as: know your data, get/set your data and view your data.

The main advantage of having a catalog of basic techniques is the description simplification of the procedures to

develop each application.

4.1 Kata #1: Say Hello to <name>

The problem:

Develop a Hello world program with ASP- Net MVC.

Procedure:

- Create a new MVC project called HelloMVC

- Create a new controller called HelloController

- Define a controller's action called SayHi2(string name)

- Send the name via the ViewData to the view ()

Public Class HelloController

Inherits System.Web.Mvc.Controller

'

' GET: /Hello/SayHi2

Function SayHi2(ByVal name As String) As ActionResult

ViewData("Name") = name

Page 55: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Return View()

End Function

- Create a new folder called Hello

- Create a new view called SayHi2.aspx (an option is the views wizard, that will assign a master page to the view)

- Add the "Hi there" legend in the h2 tag and a reference to ViewData("Name") to display any name you want using

a script code tag <%= %>

- Execute the project and go to URL

http://localhost:1926/hello/sayhi2?name=Pepe

This will display the greetings.

Page 56: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

4.2 Kata #2: Basic CRUD with simple DB

Lets play with a database and make some create, read, update and delete (CRUD).

The problem:

Develop an application capable of maintain a simple movie database (one table).

Page 57: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Procedure:

Create a new MVC project called MVCMovieDemo.

1. Create a DB called MoviesDB.mdf in the App_Data folder.

2. Create a table called Movies with 3 fields: id, title and web site. Set ID as primary key.

3. Create LINQ to SQL Data classes, and rename table Movies to Movie in design surface.

4. Create a controller called MoviesController.

4.1 Create an member instance of the DB data context to access the DB.

5. Define Index action method to retrieve a list of all the movies in the DB.

6. Define Details action method to retrieve the details of a movie, passing the id of the record.

7. Define Edit action methods to display item details and apply changes.

8. Define Create action method to create a new item, assign the values passed and insert a new record in the DB.

9. Create a new view called Index to show a List. Edit action links to allow details and edit operations.

10. Create a new view called Details to show an item. Edit action link to allow edit operation.

11. Create a new view called Edit to edit an item.

12, Create a new view called Create to create new movie item.

Controller's code is provided to see details of each operation. in fact, is the only class you need to edit to define

the app behavior.

Page 58: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

4.2.1 Controller code

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Mvc.Ajax;

using MvcSample1.Models;

namespace MvcSample1.Controllers

{

public class MoviesController : Controller

{

MoviesDataClassesDataContext context = new MoviesDataClassesDataContext();

//

// GET: /Movies/

public ActionResult Index()

{

//get the list of items in the DB

var list = from item in context.Movies orderby item.Title select

item;

return View(list.ToList());

}

//

// GET: /Movies/Details/5

public ActionResult Details(int id)

{

//show details from an item

Movie movie= context.Movies.Single(m=>m.ID ==id );

Page 59: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

return View(movie);

}

//

// GET: /Movies/Create

public ActionResult Create()

{

return View();

}

//

// POST: /Movies/Create

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Create(FormCollection collection)

{

try

{

//Create new instance and add the data

Movie v = new Movie

{

Title = collection["Title"],

Website = collection["Website"],

};

//create a new record

context.Movies.InsertOnSubmit(v);

context.SubmitChanges();

return RedirectToAction("Index");

}

catch

{

Page 60: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

return View();

}

}

//

// GET: /Movies/Edit/5

public ActionResult Edit(int id)

{

//show details of item to update

Movie movieToEdit = context.Movies.Single(m => m.ID == id);

return View(movieToEdit);

}

//

// POST: /Movies/Edit/5

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Edit(int id, FormCollection collection)

{

Movie movie = context.Movies.Single(m => m.ID == id);

try

{

// apply changes to item and update

movie.Title = collection["Title"];

movie.Website = collection["Website"];

context.SubmitChanges();

return RedirectToAction("Index");

}

catch

{

return View(movie);

Page 61: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

}

}

}

}

4.3 Kata #3: a blog engine

Can we do something more than ABCD as usual?

Yes, please!!!!! Even when basic CRUD is important to get your hands dirty, nothing like take something a little

more complicated to explore how far we can go.

Blogs are simple applications to publish messages and receive comments; but if you have a business plan, maybe

you can do something like Blogger.

The problem:

Develop a blogging engine supports blog posts, comments and categories. A blog post can have only one category

and as many comments as possible.

Because a blog is a little more complex than a basic CRUD, this time 10 or 15 lines will not be enough to tell how to

do one. So I divide the procedure for each MVC modules.

4.3.1 The blog model

In this case we will use the Entity framework to show and explore its capabilities, and apply the techniques

previously exposed.

Procedure:

1. Create a new MVC project called MvcBlog

2. Create a new SQL database called BlogDB

2.1 Create 3 tables in the DB: Categories, Posts and Comments. Remember to set the primary key in each table.

2.2 Create a new DB diagram and add the db objects (tables) to edit the relationships of the tables (and to have an

ER diagram too).

2.3 Define the relationships between the tables.

- One or more posts must belong to a category.

- One or more comments must be related to a post.

Page 62: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

3. In the models folder create a new Entity Data Model called BlogModel.edmx. Select the BlogDB to generate the

model and the 3 tables you created in the DB.

3.1 Rename entities from plural to singular.

4.3.2 The blog controllers

Page 63: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

In kata #2 we only create one controller. Why?

Well, just because we have only ONE table in our DB. In this case we have 3 tables in the DB, so if we follow the 1:1

relation logic, we will need 3 controllers, right?

But a blog is not just a set of CRUD views.

Its a fact that we will need complete CRUD for administration of Categories and Posts, if we stand in the blog

author's role.

But from a visitors perspective, when you enter a blog, generally the home page expose the most recent posts.

From there, you can select a post and show its details and there you can add a comment or see the comments

associated to that post.

Another nice thing to do is to retrieve a list of posts related to one category.

All these capabilities are not exactly CRUD operations, so it seems we'll need 4 controllers:

CategoriesController, initially for the categories CRUD operations.

PostsController, initially for the posts CRUD operations.

HomeController, for visitors.

CommentsController, for edit and retrieve comments.

4.3.2.1 Categories Controller

Procedure:

1. Create a new controller named CategoriesController.

2. Define the Index action method to get a list of all the categories.

3. Define the Details action method to get the details from an item.

4. Define the Edit action methods to edit one item.

5. Define the Create action method to create a new item.

Code

using System;

using System.Collections.Generic;

using System.Linq;

Page 64: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

using System.Web;

using System.Web.Mvc;

using System.Web.Mvc.Ajax;

using MvcBlog.Models;

namespace MvcBlog.Controllers

{

public class CategoriesController: Controller

{

BlogDBEntities dbentities =new BlogDBEntities();

// GET: /Category/DotNet

public ActionResult Category(string catName)

{

//get the posts related to this category

//var categoryPosts = from p in dbentities.PostSet where

(p.Categories.Title == catName) select p;

//return View( categoryPosts );

return View();

}

public ActionResult Index() {

return View(dbentities.CategorySet.ToList ());

}

//

// GET: /Categories/Details/5

public ActionResult Details(int id)

{

//get the posts related to this category

var item = (from c in dbentities.CategorySet where(c.Id == id) select

c).FirstOrDefault ();

return View(item);

}

//

// GET: /Categories/Create

Page 65: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

public ActionResult Create()

{

return View();

}

//

// POST: /Categories/Create

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Create([Bind(Exclude ="Id")]Category item)

{

if(!ModelState.IsValid)

return View();

try

{

// add the item to the items set and save

dbentities.AddToCategorySet (item);

dbentities.SaveChanges();

return RedirectToAction("Index");

}

catch

{

return View();

}

}

//

// GET: /Categories/Edit/5

public ActionResult Edit(int id)

{

//get the post to edit

var item = (from c in dbentities.CategorySet where(c.Id == id) select

c).FirstOrDefault();

return View(item);

}

//

// POST: /Categories/Edit/5

[AcceptVerbs(HttpVerbs.Post)]

Page 66: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

public ActionResult Edit(Categoryitem2Edit)

{

if(!ModelState.IsValid)

return View();

try

{

//apply the changes to the post and save it

var originalItem = (from c in dbentities.CategorySet where(c.Id ==

item2Edit.Id) select c).FirstOrDefault();

dbentities.ApplyPropertyChanges(originalItem.EntityKey.EntitySetName,

item2Edit);

dbentities.SaveChanges();

return RedirectToAction("Index");

}

catch

{

return View();

}

}

}

}

4.3.2.2 Posts controller

Procedure:

1. Create a new controller named PostsController.

2. Define the Index action method to get a list of all the posts.

3. Define the Details action method to get the details from an item.

3.1 To get the category from the item, you must make a LINQ to Entities query to get the value of the foreign key

(index).

3.2 With the index value, search the CategoriesSet to get the category name.

3.3 Assign the value to the ViewData to consume it later on the view.

int categoryID =

(int)item.CategoriesReference.EntityKey.EntityKeyValues.First(k => k.Key ==

"Id").Value;

//and then its name from the Category set

Page 67: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

string categoryName =(string) dbentities.CategorySet.First (v=>v.Id

==categoryID ).Title ;

//return the category name in the ViewData

ViewData["category"] = categoryName;

4. Define the Edit action methods to edit one item.

4.1 In the first edit method, pass the categories as a selectList to the ViewData["categories"] to populate a

dropdown list in the view, to allow changing the category.

this.ViewData["categories"] = new

SelectList(dbentities.CategorySet.ToList(),"Id", "Title");

4.2 In the second edit method, where changes are applied, apply the changes from the edited to the original item.

All fields are saved, except the categoryId foreign Key. To save the category you must get the category from its set

searching it using the formcollection value and then assign the category to the category reference of the post

(what a mess).

int index = int.Parse(formItems["CategoryId"]);

Category categ = (from c in dbentities.CategorySet where(c.Id == index)select

c).First();

//and then assign it to the reference of the post

originalItem.CategoriesReference.Value = categ;

Now your item is editable.

5. Define the Create action methods to create a new item.

5.1 In the first create method, pass the categories as a selectList to the ViewData["categories"] to populate a

dropdown list in the view, to allow changing the category.

this.ViewData["categories"] = new

SelectList(dbentities.CategorySet.ToList(),"Id", "Title");

5.2 In the second create method, you must change the method parameters, adding a FromsCollection to get the

values from input elements.

5.3 Solution is similar to edit, where you get the index of the list, get the item from Categories and then assign it to

the new item.

//add the Now date/time to the item

item.PublishDate = DateTime.Now;

//validate if a category is selected; if not pick the first

if(formItems["CategoryId"].Length == 0) formItems["CategoryId"] = "1";

//now get the selection list index

intindex = int.Parse(formItems["CategoryId"]);

//get the appropiate category

Category categ = (from c in dbentities.CategorySet where(c.Id == index)select

c).First();

Page 68: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

//and assign it to the new item

item.CategoriesReference.Value = categ;

// add the item to the items set and save

dbentities.AddToPostSet (item);

dbentities.SaveChanges();

Code

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Mvc.Ajax;

using MvcBlog.Models;

namespace MvcBlog.Controllers

{

[HandleError]

public class PostsController : Controller

{

//instance to access DB entities

BlogDBEntities dbentities = new BlogDBEntities();

public ActionResult Index()

{

//get all items to list 'em ordered by date

var allPosts = from p in dbentities.PostSet orderby p.PublishDate

descending select p ;

return View(allPosts);

}

//

Page 69: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

// GET: /Post/3

public ActionResult Post(int id)

{

//return the datail from a post

var item = (from c in dbentities.PostSet where (c.Id == id)

select c).FirstOrDefault();

return View(item);

}

//

// GET: /Posts/Details/5

public ActionResult Details(int id)

{

//return the detail from a post

var item = (from c in dbentities.PostSet where (c.Id == id)

select c).FirstOrDefault();

//get the category index from the item Entity key

//code snippet from :

//http://social.msdn.microsoft.com/Forums/en-

US/adodotnetentityframework/thread/131edf35-0171-4376-a4dd-54e1c08958d9

int categoryID =

(int)item.CategoriesReference.EntityKey.EntityKeyValues.First(k => k.Key ==

"Id").Value;

//and then its name from the Category set

string categoryName =(string) dbentities.CategorySet.First

(v=>v.Id ==categoryID ).Title ;

//return the category name in the ViewData

ViewData["category"] = categoryName;

return View(item);

}

Page 70: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

//

// GET: /Posts/Create

public ActionResult Create()

{

//to populate the categories dropdown list lets pass

//the categories in the ViewData

this.ViewData["categories"] = new SelectList(dbentities.CategorySet.ToList(),

"Id", "Title");

//this.ViewData["categoryid"] = new Category();

return View();

}

//

// POST: /Posts/Create

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Create([Bind(Exclude = "Id")]Post item,

FormCollection formItems)

{

if (!ModelState.IsValid)

return View();

try

{

//add the Now date/time to the item

item.PublishDate = DateTime.Now;

//validate if a category is selected; if not pick the first

if (formItems["CategoryId"].Length == 0)

formItems["CategoryId"] = "1";

//now get the selection list index

int index = int.Parse(formItems["CategoryId"]);

//get the appropiate category

Category categ = (from c in dbentities.CategorySet where

(c.Id == index) select c).First();

Page 71: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

//and assign it to the new item

item.CategoriesReference.Value = categ;

// add the item to the items set and save

dbentities.AddToPostSet (item);

dbentities.SaveChanges();

return RedirectToAction("Index");

}

catch

{

return View();

}

}

//

// GET: /Posts/Edit/5

public ActionResult Edit(int id)

{

//return the item to edit

var item2Edit = (from c in dbentities.PostSet where (c.Id == id)

select c).FirstOrDefault();

//to populate the categories dropdown list lets pass

//the categories in the ViewData

this.ViewData["categories"] = new SelectList(dbentities.CategorySet.ToList(),

"Id", "Title", item2Edit.Categories.EntityKey);

//get the category index from the item Entity key

int categoryID =

(int)item2Edit.CategoriesReference.EntityKey.EntityKeyValues.First(k => k.Key

== "Id").Value;

//and then its name from the Category set

string categoryName = (string)dbentities.CategorySet.First(v =>

v.Id == categoryID).Title;

Page 72: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

//return the category name in the ViewData

ViewData["category"] = categoryName;

return View(item2Edit);

}

//

// POST: /Posts/Edit/5

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Edit(Post item2Edit,FormCollection formItems)

{

if (!ModelState.IsValid)

return View();

try

{

//get the original item,

var originalItem = (from c in dbentities.PostSet where(c.Id

== item2Edit.Id ) select c).FirstOrDefault();

//change category id

//try to change value in this way produce an Invalid op error

//item2Edit.CategoriesReference.EntityKey.EntityKeyValues[0].Value =

int.Parse(formItems["categories"]);

//originalItem.CategoriesReference.EntityKey.EntityKeyValues.SetValue

(int.Parse(formItems["categories"]),0);

//apply the changes to the original item

dbentities.ApplyPropertyChanges(originalItem.EntityKey.EntitySetName,

item2Edit);

//now change the category (5 hours to find out how to do it)

//first get it from the category set

//http://stackoverflow.com/questions/826537/how-do-i-update-an-objects-

foreign-key-value-with-linq-to- entities

Page 73: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

int index = int.Parse(formItems["CategoryId"]);

Category categ = (from c in dbentities.CategorySet where

(c.Id == index) select c).First();

//and then assign it to the reference of the post

originalItem.CategoriesReference.Value = categ;

//save changes to the item

dbentities.SaveChanges();

return RedirectToAction("Index");

}

catch(Exception e)

{

//if View(), the page have a null Model

ViewData["edit error"] = e.Message + e.StackTrace ;

return View( );

}

}

}

}

4.3.2.3 Home controller

Procedure:

- Create a new controller named HomeController.

- Create an instance of the data model.

- Show a list with the last 3 most recent posts.

1. Modify Index action method adding a variable named recentPosts that will receive the result from a LINQ to

Entities query to retrieve the top 5 records in the DB.

2. Pass the recentPosts variable to the return View.

//get the 3 most recent posts and order them by date

var recentPosts= (from p in dbentities.PostSet.Top("3") orderby p.PublishDate

descending selectp) ;

return View(recentPosts);

Page 74: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Code

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using MvcBlog.Models;

namespace MvcBlog.Controllers

{

[HandleError]

public class HomeController : Controller

{

BlogDBEntities dbentities = new BlogDBEntities();

public ActionResult Index()

{

//get the 3 most recent posts and order them by date

var recentPosts= (from p in dbentities.PostSet.Top("3") orderby

p.PublishDate descending select p) ;

return View(recentPosts);

}

public ActionResult About()

{

return View();

}

}

}

4.3.2.4 Comments controller

Well, it´s time for comments.

Page 75: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Comments are not in control of the post author. Users add comments related to a post, and there they stay.

To start:

- Create a new controller named CommentsController.

- Create an instance of the data model.

Add comment

A blog's add comments page looks like this:

So what we need is:

- create the Create action methods. The first to catch the id of the post to associate the comment. The second to

save the comment data.

View comments

- Create the Post(id) action method to retrieve the comment associated to a post.

- Make a LINQ to entities query to retrieve all comments associated to the post.

- Assign to dataView the id, title and text of the post to show it at the beginning.

Code

using System;

using System.Collections.Generic;

Page 76: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Mvc.Ajax;

using MvcBlog.Models;

namespace MvcBlog.Controllers

{

public classCommentsController: Controller

{

//instance to access DB entities

BlogDBEntities dbentities =new BlogDBEntities();

//show the form to add the comment

public ActionResult Create(intid) {

ViewData["postid"] = id;

return View();

}

//create the new comment

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Create([Bind(Exclude ="Id")]Comment item,

FormCollection fc)

{

try

{

//set the published date

item.PublishDate = DateTime.Now;

//now get the selection list index

int index = int.Parse ( fc["postid"]);

//get the appropiate category

Post pos = (from p in dbentities.PostSet where(p.Id == index)select

p).First();

//and assign it to the new item

item.PostsReference.Value = pos;

// add the item to the items set and save

dbentities.AddToCommentSet(item);

dbentities.SaveChanges();

Page 77: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

return RedirectToAction("../Home");

}

catch

{

return View();

}

}

//get the comments from a post

public ActionResult Post(int id)

{

//get the post title and text to put at the beginning

Post pos = (from p in dbentities.PostSet where(p.Id == id)select

p).First();

ViewData["postid"] = pos.Id ;

ViewData["postTitle"]=pos.Title ;

ViewData["postText"] = pos.Message ;

//get all comments associated to the post

//var comentarios = (from c in dbentities.CommentSet where

((int)(c.PostsReference.EntityKey.EntityKeyValues.GetValue (0) ) == id)

select c).ToList ();

var comentarios = (from c in dbentities.CommentSet where(c.Posts.Id

== id) select c).ToList();

return View(comentarios );

}

}

}

4.3.3 The blog views

4.3.3.1 Categories views

Procedure:

- Create a new folder called Categories.

- Create a view called Index to retrieve the list of all items.

- Create a view called Details to display the fields of an item.

-Create a view to edit an item. Be sure to delete the Id field in the aspx page, cause it is not needed.

- Create a view called Create to make a new item.

Page 78: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

4.3.3.2 Posts views

Procedure:

- Create a new folder called Posts.

- Create a view called Index to retrieve the list of all items.

- Create a view called Details to display the fields of an item.

-Create a view to edit an item. Be sure to delete the Id and PublicDate fields in the page.

1. Add a drop down list to display categories. Use the ViewData["categories"] to populate the list.

- Create a view called Create to create a new item. Be sure to delete the Id and PublishDate fields in the aspx page,

cause they are not needed.

1. Add a drop down list to display categories. Use the ViewData["categories"] to populate the list.

<p>

<label for="CategoryId">Category:</label>

<%= Html.DropDownList("Category", (IEnumerable<SelectListItem>)ViewData["categories"], "Tech")%>

<%= Html.ValidationMessage("Category", "*")%>

</p>

The problem with this comes when you want to save the new item, because the following error is shown:

There is no ViewData item with the key 'Category' of type 'IEnumerable<SelectListItem>'.

This happens because no item in the drop down list is selected. And because no Category is assigned to the new

item (remember is the foreign key). This is fixed in the Create method of the controller.

Where is the post category?

Ah-ha!!! View generator wizard doesn´t add the category field of the post!!!!

And that includes the Create, details and Edit views.

As commented, you have to add labels or dropdown lists to show and edit this value. Is not simple, because

Entities queries are quite obscure.

Page 79: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

4.3.3.3 Home view

The home page is where the user is going to start his visit.

Recent blog entries

The home page view must display, as many blogs do, a list of the most recent post.

The HomeController actually has an action method to do this, but I don´t want the Views wizard to generate a

table with my entries.

I prefer a format like

Title

-------------------------

Message text

....

Publish Date: 1/1/2009

Comments: N

To do this, I can't depend on generated code, because it hasn't any style picker.

Seems that its time to DIY but how?

Instead of thinking about using server controls or any other thing, generate a view that shows a list.

Then copy the loop that is inside of the aspx page, put it before the original loop, and start to play with the content

format.

You can accomplish something like this

Page 80: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Then just erase the original table with its loop, and you are done.

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Recent entries</h2>

<% foreach(var item in Model) { %>

<h3><%=Html.Encode(item.Title) %></h3>

<p><%=Html.Encode(item.Message) %></p>

<small><%=Html.Encode(String.Format("{0:g}", item.PublishDate))

%></small>

<br/>

<small>Comments: <%=Html.Encode(item.Comments.Count () )%></small>

<hr/>

<% } %>

</asp:Content>

Changes to the master page

Page 81: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

To change the application title or to add some extra menu options, just edit the Site.Master file in folder Shared.

To change the title, change the text in the title div

<div id="title">

<h1>My MVC Blog</h1>

</div>

To add more menu options add tags to the UL list:

<div id="menucontainer">

<ul id="menu">

<li><%= Html.ActionLink("Home", "Index", "Home")%></li>

<li><%= Html.ActionLink("Posts", "../Posts", "Home")%></li>

<li><%= Html.ActionLink("Categories", "../Categories", "Home")%></li>

<li><%= Html.ActionLink("About", "About", "Home")%></li>

</ul>

</div>

4.3.3.4 Comments view

Add a comment, please

To add comments.

- Create a new view in the Comments folder, called Create. Only title and message field most be visible.

- Add 2 links in the Home view to each comment with the text "View" and "Add new"

- Set View link to URL ../Comments/Post/n to check the comments associated to that post

- Set Add new link to URL ../Comments/Create/n to add the comment associated to that post

Page 82: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

- Generate the Create view to add comments. use the wizard to make a create view. Delete the Id and Date fields.

- Add a hidden field to hold the post id, so you can save the comment and associate to the post.

Now let´s view the comments

- Create the Post view in the Comments folder. With the wizard you can generate a List view.

Page 83: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

4.3.4 Comments

If you want to check the full code, I upload it to planetsourcecode.com

Check it here.

There's a lot to do with a blog. For instance:

- Add paging to the posts list.

- Add a post index.

- Adding a better editor for messages like FCKEditor.

- Add user roles and security.

- Add this comments validations stuff (the one with the funny letters and numbers).

4.4 Kata #4: File upload

Let's take a break from DBs and do something with files.

A common need in many sites is to let the users upload their files (documents, images, videos).

This functionality is the base for sites like Flickr, Scribd, YouTube and many others.

To implement this, we need to create a folder where the files will be saved.

http://towardsnext.wordpress.com/2009/04/17/file- upload-in-aspnet-mvc/

Three basic operations are needed:

Page 84: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

1. Upload a file.

2. Consult a list of uploaded files.

3. View the file content

To make it visual, lets display images.

4.4.1 Upload controller

Procedure:

1. Create a new controller named FileUploadController.

2. Define the Index action method to show a list of the files uploaded.

3. Define the Upload action method to handle the file transfer and saving on the folder /Uploads.

//transfer the files fron the client and save them on the uploads folder

public ActionResult Upload()

{

foreach(string inputTagName in Request.Files)

{

HttpPostedFileBase file = Request.Files[inputTagName];

if(file.ContentLength > 0)

{

string filePath =

Path.Combine(HttpContext.Server.MapPath("../Uploads")

, Path.GetFileName(file.FileName));

file.SaveAs(filePath);

}

}

return RedirectToAction("FilesUploaded", "FileUpload");

}

4. Define the FilesUploaded action method to get a list of all files in the Uploads folder. The list will be send to a

view to show all the files and give the chance of display a specific image.

///<summary>

///Get the list of uploaded files and launch a list view

///</summary>

Page 85: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

///<returns></returns>

public ActionResult FilesUploaded()

{

string path = HttpContext.Server.MapPath("../Uploads");

DirectoryInfo dirInfo = new DirectoryInfo(path);

FileInfo[] files = dirInfo.GetFiles();

return View( files.ToList () );

}

5. Define the ViewImage(string fileName) action method to get and display an image; actually what is important is

the image URL that will be composed from the base Uploads path and the name of the file selected.

///<summary>

///Constructs the image URL and send it to the view

///</summary>

///<param name="fileName"></param>

///<returns></returns>

public ActionResult ViewImage(string fileName)

{

ViewData["imagen"] = "../Uploads/"+ fileName;

return View();

}

4.4.2 Upload views

Procedure:

1. Create a new folder Views/FileUpload

4.4.2.1 Upload file view

Procedure:

1. Add a new view from the Index action method, with no options to get a clean view.

Page 86: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

2. In the aspx file, add a Html form with a textbox, a file input control to search and specify the name of the file to

upload and a button to upload the file.

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent"

runat="server">

<h2>Files uploaded to server</h2>

<div id="dialog" title="Upload files">

<% using(Html.BeginForm("Upload", "FileUpload", FormMethod.Post, new{

enctype = "multipart/form- data"}))

{%><br/>

<p><input type="file" id="fileUpload" name="fileUpload"

size="23"/>;</p><br/>

<p><input type="submit" value="Upload file"/></p>

<% }%>

</div>

</asp:Content>

The code call the Upload action method, that makes the magic of transfer and copy the file.

Page 87: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

4.4.2.2 Uploaded files list

Procedure:

1. Add a new view from the FilesUploaded action method, with no options to get a clean view.

2. This view receives the /Uploads directory file list as a parameter. This can be specified changing the Inherits

property in the @Page tag, by adding the data type expected to do the processing (in this case, a List of FileInfo

objects).

<%@Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

Inherits="System.Web.Mvc.ViewPage<List<System.IO.FileInfo>>"%>

3. In the second content tag, add a table to show the files list and a foreach loop to process the List received.

<asp:ContentID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>FilesUploaded</h2>

<table>

<tr>

<th>

Files uploaded

</th>

<th></th>

Page 88: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

</tr>

<% foreach(var item in Model) { %>

<tr>

<td>

<%=Html.Encode(item.Name )%>

</td>

<td>

<%=Html.ActionLink("View", "ViewImage", new{ fileName=item.Name

}) %>

</td>

</tr>

<% } %>

</table>

</asp:Content>

NOTE: be sure the variable name used in the new{} section of the ActionLink is the same that the parameter

received by the action method.

4.4.2.3 View image

Page 89: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Procedure:

1. Add a new view from the ViewImage action method, with no options to get a clean view.

2. Add an img tag to display the image, and in the src property place the ViewData instance to specify the image

path.

<asp:ContentID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>ViewImage</h2>

<img alt="imagen" src="<%= ViewData["imagen"]%>"/>

<hr/>

</asp:Content>

4.4.3 Comments

This file uploader don´t differ too much from its ASP or ASP.Net counterparts.

First interesting thing in here is that in this case, no model was needed. All data came from the .Net framework IO

support (directory and file information).

Second interesting thing is the fact that you can define manually the object type from the parameter received by

the view. In the precedent samples, all this was handled by the wizard, and we trust it for the job.

Page 90: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

However, you may not need the wizard always, specially when no DB or model is part of your solution.

4.5 Kata #5: RSS feed reader

Now that we pass thru DBs and files, let´s try a standard online data source: RSS.

A very popular data source is the RSS channels that many blogs include as part of the data exchange services.

4.5.1 RSS controller

1. Create a new controller called RSSController

2. Define a new action method called RSSReader, where the RSS processing is taking place; the method will launch

a view to display the results.

At this point, there are different options to process the content from the RSS:

Page 91: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

a. Hard code the format to be sent to the view, and create a string with the Html.

b. Process the content with a XSL template (more flexible if you need some changes).

4.5.1.1 Hard coded formatting

For the hard-coded formatting option:

a.1 Define a RSSReaderHC action method

a.2 Define a request-response HTTP pair (and define a proxy object if you have a proxy in your network)

a.3 Get the response, assign it to a XMLDocument.

a.4 Procces the XML document nodes and assign some HTML tags to format the output. Then pass this through the

ViewData.

//Read a feed and get its content

//then format content with html tags

public ActionResult RSSReaderHC()

{

string strRssUrl = "http://www.asp101.com/rss/"; //asp.net 101 news

rss

StringBuilder result=new StringBuilder();

//prepare the request

HttpWebRequest request =

(HttpWebRequest)HttpWebRequest.Create(strRssUrl);

//if you have a proxy, then fill this; otherwise comment it

WebProxy proxy = new WebProxy("proxy.netdomain",8080);

proxy.Credentials = new NetworkCredential("guest", "p4$$w0rd");

request.Proxy = proxy;

//call for response

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

Stream rssStream = response.GetResponseStream();

//load content in a XML doc

XmlDocument rssDoc=new XmlDocument();

rssDoc.Load(rssStream );

//get the node list from the rss

XmlNodeList rssItems = rssDoc.SelectNodes("rss/channel/item");

//now process the nodes (link, title, description)

//to add html tags

result.Append ("<ul>");

Page 92: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

foreach(XmlNode xnode in rssItems)

{

result.Append ("<li><a href="+ xnode.SelectSingleNode

("link").InnerText +"target='_blank'>"+ xnode.SelectSingleNode

("title").InnerText +"</a>"+" </li>");

}

result.Append ("</ul>");

ViewData["rss"] = result.ToString();

return View( );

}

4.5.1.2 XSL formatting

See document: 1479_Using_XSLT_to_Transform_XML_Using_ASPNET.5

XSL formatting is a more flexible way to define how data is going to be rendered in a page. The great advantage is

that definition is kept outside the code, so any adjustment ain't imply code modification.

A simple XSL file to format the RSS entries is the following:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

xmlns:msxsl="urn:schemas- microsoft-com:xslt" exclude- result-

prefixes="msxsl"

>

<xsl:outputmethod="xml" indent="yes"/>

<xsl:template match="channel">

<h2>

<xsl:value-of select="title"/>

</h2>

<hr></hr>

<p>

<xsl:value-of select="description"/>

</p>

<!--Items go here-->

<xsl:apply-templates/>

</xsl:template>

<xsl:template match="item">

Page 93: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

<a>

<xsl:attribute name="href">

<xsl:value-of select="link"/>

</xsl:attribute>

<xsl:value-of select="title"/>

</a>

<hr></hr>

</xsl:template>

</xsl:stylesheet>

For the XSL formatting option:

b.1 Define a RSSReaderHC action method

b.2 Define a request-response HTTP pair (and define a proxy object if you have a proxy in your network)

b.3 Get the response, assign it to a XPath document.

b.4 Load the XSLT file defined to format the data.

b.5 Pass the XML document to the XSL document and process it. Get the resulting string and pass this through the

ViewData.

public ActionResult RSSReaderXSL()

{

string strRssUrl = "http://www.asp101.com/rss/"; //asp.net 101 news

rss

string resHTML;

//prepare the request

HttpWebRequest request =

(HttpWebRequest)HttpWebRequest.Create(strRssUrl);

//if you have a proxy, then fill this

WebProxy proxy = new WebProxy("proxy.mynet", 8080);

proxy.Credentials = new NetworkCredential("guest", "p4$$w0rd");

request.Proxy = proxy;

//call for response

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

//get the rss content

Stream rssStream = response.GetResponseStream();

//load content in a XML doc

// Load the XML

Page 94: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

XPathDocument doc = new XPathDocument(rssStream);

// Load the style sheet.

XslCompiledTransform xslt =new XslCompiledTransform();

xslt.Load(Server.MapPath("../Views/RSS/RSS.xslt"));

//apply the format to the content and put it

//on a string to send it to the view

MemoryStream ms = new MemoryStream();

XmlTextWriter writer = new XmlTextWriter(ms, Encoding.ASCII);

StreamReader rd = new StreamReader(ms);

xslt.Transform(doc, writer);

ms.Position = 0;

resHTML = rd.ReadToEnd();

rd.Close();

ms.Close();

ViewData["rssText"] = resHTML;

return View();

}

4.5.2 Hard coded view

The resulting view is actually very simple, because all formating was made in the controller. All you have to do is

add a <%= %> tag to display the ViewData["rss"] content.

<%@Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

Inherits="System.Web.Mvc.ViewPage"%>

<asp:ContentID="Content1" ContentPlaceHolderID="TitleContent" runat="server">

RSSReaderHC

</asp:Content>

<asp:ContentID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>RSSReaderHC</h2>

<%=ViewData["rss"]%>

</asp:Content>

Page 95: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

4.5.3 XSL view

Create a view called RSSReaderXSL and use the same approach: just show the DataView content.

Page 96: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

4.6 Kata #6: Sending e.mail

To finish with the "trivial" techniques, let's see one of the most useful rabbit in the hat.

Sooner or later, you´ll need to send and e-mail. Because you want feedback about something, or want to send a

message with a confirmation; there are many scenarios where this can be done.

So, what do we need to send an e-mail via a web page?

Sending an e-mail implies to use the SMTP (Simple Mail Transfer Protocol) protocol.

The .NET Framework version 1.x included a number of classes in the System.Web.Mail class that allowed

programmatically sending an email with a few lines of code. While this namespace and these classes still exist in

the .NET Framework version 2.0, they have been deprecated in favor of new mail- related classes found in the

System.Net.Mail namespace.

When sending an email from a page you will, typically:

1. Create a MailMessage object

2. Assign its properties

3. Create an instance of the SmtpClient class

4. Specify details about the SMTP server to use

5. Send the MailMessage via the SmtpClient object's Send method

Well, it sounds easy, isn´t it?

As usual, create a new MVC project.

Page 97: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

NOTE: a few weeks ago I had to reinstall my VS 2k8. So, when I create this project, something looks wrong. No

highlighting of MVC clases or attributes, and it seems that MVC reference it's gone.

Solution: reinstall your ASP.Net MVC 1.0 and add the System.Web.Mvc reference to the project.

4.6.1 SendMail controller

1. Create a new controller called SendMailController

2.1 Define the index action method to show a blank page.

Page 98: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

2.2 Define the EditEMail action method to show the mail edition UI.

3. Define a new action method called SendEMail, where the e-mail will be forged and transmitted ; the method will

launch a view to display the results.

4.6.1.1 Code

namespace MvcSendMail.Controllers

{

public class SendMailController: Controller

{

public ActionResult Index()

{

returnView();

}

///<summary>

///Launch the email edit view

///</summary>

public ActionResult EditEMail()

{

return View();

}

///<summary>

///When send is pushed, here is where the mail is prepared and

launched

///</summary>

public ActionResult SendEMail(string mailTo,string subject, string

message)

{

MailMessage mm = new MailMessage("[email protected]", mailTo);

mm.Subject = subject;

mm.Body = message;

mm.IsBodyHtml = false;

//specify the host address to the client

SmtpClient smtp = new SmtpClient("200.0.2.7");

smtp.Send (mm);

Page 99: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

return View("Index");

}

}

}

4.6.2 SendMail views

Procedure:

1. Create a new folder Views/SendMail

4.6.2.1 Edit e-mail view

Procedure:

1. Add a new view from the Index action method, with no options to get a clean view.

2. Add labels and textboxes to get the e-mail address, subject and message. Add a button to send the e-mail.

4.6.2.2 Problems with the EnterpriseServices DLL

I tried to run the app to see the UI in te browser and I get this error: "Compiler error message:

System.EnterpriseServices.dll' could not be found"

Page 100: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Fortunately, I found a post with the fix. I wrote a .bat with the following:

rem Fix error "Could not load file or assembly System.EnterpriseServices"

"C:\Archivos de programa\Microsoft SDKs\Windows\v6.0A\bin\gacutil.exe" /i

Microsoft.NET/Framework/v2.0.50727/System.EnterpriseServices.dll

pause

But it seems that the file is not in my machine.

Ups!! the path dude, the PATH!!!!

"C:\Archivos de programa\Microsoft SDKs\Windows\v6.0A\bin\gacutil.exe" /i

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.EnterpriseServices.dll

Page 101: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Ufff. Everything back to normal. Well...almost.

4.6.2.3 Editing your view with HTML helpers

Because this time there is no good old wizard to generate my UI, I design the view with asp controls. The code

looks like this:

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>EditEMail</h2>

<% using(Html.BeginForm("SendEMail", "SendMail", FormMethod.Post, new{

enctype = "multipart/form- data"}))

{%>

<asp:Label ID="Label1" runat="server" Text="Send to:"></asp:Label>

<asp:TextBox ID="txtMail" runat="server"></asp:TextBox>

<br/>

<asp:Label ID="Label3" runat="server" Text="Subject:"></asp:Label>

<asp:TextBox ID="txtSubject" runat="server"></asp:TextBox>

<br/>

<br/>

<asp:Label ID="Label2" runat="server" Text="Message:"></asp:Label>

<br/>

<asp:TextBox ID="txtMessage" runat="server" Height="126px"

Width="590px"></asp:TextBox>

<br/>

<p><input type="submit" value="send it"/></p>

<% }%>

</asp:Content>

Page 102: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

The error displayed in the browser was: Exception Details: System.Web.HttpException: Control

'ctl00_MainContent_txtMail' of type 'TextBox' must be placed inside a form tag with runat=server.

Looks like something messy happens with standard ASP controls

So, I decided to use HTML helpers instead, and it just works fine! (also it looks cleaner).

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Edit email message</h2>

<% using(Html.BeginForm("SendEMail", "SendMail", FormMethod.Post, new{

enctype = "multipart/form- data"}))

{%>

<br/>

Mail to:<%=Html.TextBox("mailTo") %>

<br/> <br/>

Subject:<%=Html.TextBox("subject") %>

<br/> <br/>

<p>Message:</p>

<%=Html.TextArea("message") %>

<br/>

<p><input type="submit" value="send it"/></p>

<% }%>

</asp:Content>

Just remember to assign the helpers the same name as the variables from method SendEMail.

Page 103: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

4.7 Final comments

As complexity grows, you can see for each case that the description level raise. This is necessary to communicate

how to implement each case, trying to be as clear as possible.

To be honest, I ain't did any previous design for the samples (pure instinct). Having the problem stated I used the

techniques in the previous chapter to develop the applications, so many decisions, specially in the blog, were made

on the fly and I tried to leave them commented for you.

The last kata was very dramatic, because of certain unexpected results of reinstalling my VS 2k8, but I believe the

experience and fixes can help you in an adverse scenario.

In the next set of katas I will include a more formal design phase, now that I have a better idea of an application

structure.

Its clear that you may want to use ASP.net MVC to do something complex for you or for a client, and that implies

additional techniques; but for the moment and to have that sense of accomplish, I feel these cases can put you on

the right track.

4.7.1 Extra, extra!!! One more way to skin the cat

Page 104: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

January, 2010.

I've been reading about ORMs and checking some products (open source & commercial) and I found Subsonic.

Just for the record, these guys have a very interesting approach, similar to Ruby on Rails, and the best of all, their

samples use the ASP.Net MVC framework, so if you want to check another paradigm, this is a good choice.

http://www.subsonicproject.com/

5 Meanwhile, ASP.Net MVC version 2 arrived

I leave for a while this document because I get involved in smart device development and some other interesting

stuff.

Today (May 27th, 2010) I received a requirement to make a prototype of a web data capture app, so I decided to

take a look at ASP.Net MVC status.

Surprise!!! Version 2 was released in 3/12/2010.

The good news (from ScootGu's blog):

1. ASP.NET MVC 2 is a compatible update to ASP.NET MVC 1 –so all the knowledge, skills, code, and extensions you

already have with ASP.NET MVC continue to work and apply going forward.

2. Source code included for ASP.NET MVC 2 under an OSI- compliant open-source license.

3. ASP.NET MVC 2 can be installed side-by-side with ASP.NET MVC 1.

4. Available for VS 2008 & 2010

I don´t know if its available for Mono, but with source code included, it's highly probable.

Download here.

Read features details in "What’s New in ASP.NET MVC 2".

5.1 Installation for VS 2008

Execute AspNetMVC2_VS2008.exe

Page 105: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

After 5 minutes, you have this screen.

When you open VS 2k8 and create a new project you will have some new options in the Web templates. In this

case I have a side by side installation with version 1.

Page 106: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

And if you proceed, again you can choose if you want some unit testing support

5.2 Lets loosen up and get alternative

Well, to check what v2 can do, let's do another data driven sample, but this time I'll use Subsonic 3 to build the

data model (I´m curious).

Create a new MVC project called MVC2Demo.

Page 107: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

5.2.1 Do the model

So first do the MODEL (generic steps):

1. Create a DB in the App_Data folder.

Page 108: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

To add tables to the DB, let's use Subsonic with its SimpleRepository mode. This let us create a set of classes that

when an instance is created and added to the repository, it create the table's schema in the DB.

2. Download Subsonic 3, copy the Subsoni 3.0.0.4 folder in the solution's folder

3. Add a reference to SubSonic.Core.dll in the project.

Page 109: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

3. In the models folder create a new class Producer with some properties.

Important: To turn a property intpo the primary key, the naming convention <table_name>ID must prevail. To let

null values in a field, add a ? next to its type.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace MVC2Demo.Models

{

public class Producer

{

public int ProducerID { get; set; }

public string Name { get; set; }

public string LastName { get; set; }

public DateTime? Birthdate { get; set; }

}

}

5.2.2 Quick & dirty test with a controller

To make a simple test of the capabilities of subsonic, let's use the default HomeController (generated by the

project) and add some code to the Index method (remember to add using SubSonic.Repository;).

Page 110: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

public ActionResult Index()

{

ViewData["Message"] = "Welcome to ASP.NET MVC!";

var repo = new SimpleRepository("SubsonicCnx",

SimpleRepositoryOptions.RunMigrations);

var record = new Producer();

record.Name = "Juan";

record.LastName = "Doe";

record.Birthdate = new DateTime(1967, 6, 1);

repo.Add(record);

return View();

}

Some of the magic is done by the RunMigration option that migrate the model for you - automatically creating and

synchronizing your DB.

To make it work, add a connection string that points to our new DB in the web.config.

<connectionStrings>

<add name="ApplicationServices" connectionString="data

source=.\SQLEXPRESS;Integrated

Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User

Instance=true" providerName="System.Data.SqlClient"/>

<add name="SubsonicCnx" connectionString ="data

source=.\SQLEXPRESS;Integrated

Security=SSPI;AttachDBFilename=|DataDirectory|DemoDB.mdf;User Instance=true"

providerName="System.Data.SqlClient"/>

</connectionStrings>

The result is a new table in the DB

No more than 10 minutes!!!

5.2.3 Show the data

To show our records, lets modify again the Index method from the HomeController, to get the data from the DB.

Page 111: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

public ActionResult Index()

{ ViewData["Message"] = "Welcome to ASP.NET MVC!";

var repo = new SimpleRepository("SubsonicCnx",

SimpleRepositoryOptions.RunMigrations);

//get the records

var producers = from p in repo.All<Producer>() orderbyp.ProducerID select p;

//send them to the view

return View(producers.ToList ());

}

And we need to add something in the view (index.aspx) to display results (basically a reference to data to display,

in this case a list of Producers, and a loop to display them)

<%@Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

Inherits="System.Web.Mvc.ViewPage<List<MVC2Demo.Models.Producer>>"%>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"

runat="server">

Home Page

</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2><%=Html.Encode(ViewData["Message"]) %></h2>

<% foreach(varitem inModel) { %>

<p><%=Html.Encode(item.Name) %>

<%=Html.Encode(item.LastName) %></p>

<%=Html.Encode(String.Format("{0:g}", item.Birthdate)) %>

<% } %>

<p>

To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc"

title="ASP.NET MVC Website">http://asp.net/mvc</a>.

</p>

</asp:Content>

And after all....ta-da!!!

Page 112: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

5.2.4 Comments

Till now, there are no surprises. Everything seems to be the same from version 1 to version 2.

About Subsonic: it's very easy to set it up. It's great to have control of the data model via class definition (at least in

SingleRepository mode) .

I know that this test is a little bit messy, because I put code in a controller that is not specific to the app, but the

spirit was to make a quick & dirty test of the infrastructure to check the basic configuration details.

5.3 Where is the producer from?

At this point, is clear that play with a single table is easy.

However, what about 2 related tables?

If we state the need of knowing where the producer is from, we'll need a catalog of places, and a relation.

So for the places, lets make a State class with an StateID and a Name, and lets add a field to the Producer class

called StateID.

To add a state:

var state = new State();

Page 113: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

state.Name = "Aguascalientes";

repo.Add(state);

Subsonic creates the new table, and modify the Producer table according to class definition (in fact, it adds 0 to the

StateID new field).

However, no explicit relation is created, in other words, no foreign key is created;

so if we want to know the state name, probably we'll have to make a join in the query, but we don´t have it

directly from the objects model.

6 ASP.Net MVC: intermediate techniques

Once you have taste your first victories after making some examples, its time to get some order in your

development process.

I think there are two things that we must do to put some quality in the new applications: design and test.

Design is basic to establish what you are going to do. In the basic katas the only design element that helps to get an

idea of what is going on, is the Entity- Relationship diagram that we made for the database.

So its very important to draw a blueprint before write a single line of code.

Page 114: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

After that, lets code; but before you reach the Views realm, its important to test the logic of your application, and

this framework its a good chance to learn and do lots of unit testing.

So these to topics will be presented in this chapter.

6.1 The app design realm

I´m sure that after an idea shows, the next step is make sure how to realize it.

Which are the questions to answer in order to turn any idea to a fact?

The basics can be the following:

What is it going to do?

How does it looks like?

What data do you need?

How does it works?

To answer these questions is not an easy task, and it's important to get this answers out of your head.

A simple question: where do we go from here? And when you want to go from point A to B, a map is very useful.

But if someone is going to use your cartography, it has to be readable; this means that symbols, drawings,

instructions need to be clear and meaningful.

In this section I present a proposal to make a software specification map that capture the whats and hows to make

your idea come true.

I like to use diagrams, because they give you a panoramic vision of where to go and what to do. But the trick here

is which diagrams to use.

My proposal is to use 4 artifacts:

1. Entity-relation diagram, for the data model design.

2. Class diagram, to state the MVC architecture and the components of the application, as well of the services the

controller(s) will offer.

3. A navigation map to state the application navigation.

6.1.1 User interface sketches

With out getting too formal, I've observe that many people like to do user interface sketches.

The main goal of these sketches is to state how information is going to be presented and witch elements will

provide some interaction.

Page 115: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Of course, if you like drawing, your sketches will look lovely, but not everybody draws with a depurate technique.

However aesthetic is not important, at least for developers; the important thing is to communicate WHAT to do.

How ever, if you want your sketches look pro, you can get the MS Expression Blend 3, that has Sketch Flow

projects.

Imagination matters, because as you have more sketches you will want to pretend how your system will be used.

However, there are lots of details of these imaginary explorations may be missed or omitted, so we'll need

additional artifacts to define these details.

6.1.2 User stories

UI sketches are a good start. But sooner or later you'll need some order in your specification, and a napkin has

agreat chance of be disposed by accident.

To avoid this, and to avoid forgetting details, there is an artifact used on agile methods called user stories.

You´ll need some cards or use a map mapping tool, a presentations editor like Power Point, or anything you can

put images and text.

Each user story card has an unique ID of this user story in the project, a short name, a weight that remarks the

effort and complexity; and statement of that focus on the who, what and why of a feature, not how.

Page 116: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

A useful construct is:

As a [user role], I want to [goal], so I can [reason].

You can add your UI sketch here and include some relevant details.

In the back of the card, you must define your confirmation (testing) conditions; this how you will know when the

user story is done and is working.

Even when is tempting just to do the sketch, all these little notes will keep you in track of the goal.

When you have a set of these cards, you will have an initial specification of your solution.

Obviously it won´t be perfect the first time. You need to refine it, but that comes naturally when you get more

involved in the problem's context.

6.1.3 Navigation maps

The most common exercise when you have your sketches is decide where to go from one UI to another.

Page 117: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

For example, suppose your app presents a login form, and after you write your user name and password, you'll be

taken to a main options menu. For each option you can have a consult form, a master/details form, a data capture

form, a CRUD form, an image carrousel,... you name it.

All these "jumps" must be traced and recorded in what is known as a navigation map.

You can represent each UI as a box, and draw lines or arrows to indicate where the user will be taken.

The navigation map can include details like witch UI control will send you to a new UI.

6.1.4 Entity relationship model

an Entity-Relationship Model (ERM) is an abstract and conceptual representation of data.

6.2 Error handling

When there´s an error in your code, the effect can be unpredictable. From a display error to a complete system's

crash.

So to avoid that scenarios its important to detect the error, show it or store it and, in the best case, fix it.

In .Net we have the all mighty try..catch ...finally structure to do this.

Page 118: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

But, how you can use it on our controllers?

6.2.1 No error handling effects

When an error occurs on an action method, and no error handling is implemented, the application will return you

to the IDE and will highlight and display the error in your code.

However, not everybody have the Visual Studio to get this level of detail.

6.2.2 What's that [HandleError] attribute?

When you create an MVC application, there is a HomeController created by default, in your Controllers folder.

Check it, and you will find a [HandleError] attribute decorating the controller's class.

If you play for a while, and an error occurs, you will see a page displayed in the browser with all the error

information for debugging porpouses.

So, in theory, if you add this attribute to your new controllers, you can have the same level of verbose when an

error occurs.

6.2.3 Action filters

See document: dd695917.aspx

6.3 The Testing realm

In fact, a controller can be instantiated directly, and action methods called, without any additional infrastructure.

You don't need an HTTP context, and you don't need a server, just a test harness.

6.3.1 Unit testing

See document: ASPNETMVCFrameworkPart2.aspx

6.3.2 Testing a controller

See document: this-is-how-asp-net-mvc-controller-actions-should-be-unit-tested.aspx

Page 119: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

6.3.3 Create a test project

6.3.3.1 Test methods

7 ASP.Net MVC: intermediate code katas

7.1 Kata #7: Prototyping the model

8 References

Some references to articles, tutorials and projects related to ASP.Net MVC framework.

8.1 Articles

8.1.1 Web Applications - Spaghetti Code for the 21st Century

See document: smli_tr-2007-166.pdf

8.1.2 Building Web Apps without Web Forms

See document: cc337884.aspx

8.1.3 An Architectural View of the ASP.NET MVC Framework

See document: AnArchitecturalViewOfTheASPNETMVCFramework.aspx

8.1.4 Hosting an entire ASP.NET MVC request for testing purposes

See document: hosting-an-entire-asp-net-mvc-request-for-testing-purposes.aspx

8.1.5 ASP.NET MVC: Securing Your Controller Actions

See document: aspnet-mvc-securing-your-controller-actions

8.1.6 Virtual Earth meets MVC

See document: virtual-earth-meets-mvc.aspx

8.1.7 Partial Rendering & View Engines in ASP.NET MVC

See document: partial-renderi.html

8.2 Tutorials

8.2.1 ASP.Net MVC tutorials

See document: mvc

8.2.2 Contact manager in Asp.Net MVC

See document: ASPNETMVCSampleProjects.aspx

8.2.3 ASP.NET MVC Sample Applications - Open-Source Examples and Tutorials

See document: ASPNETMVCSampleApplicationsOpenSourceExamplesTutorials

Page 120: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

8.2.4 NerdDinner ASP.NET MVC Tutorial

See document: aspnetmvc-nerdinner_v1.pdf

8.2.5 Scott Guthrie’s ASP.net MVC Tutorial Links

See document: scott-guthries-aspnet-mvc-tutorial-links

8.2.6 ASP.NET MVC - Part 1

See document: aspnet_mvc.aspx

8.2.7 ASP.NET MVC Preview: Using The MVC UI Helpers

See document: aspnet-mvc-preview-using-the-mvc-ui-helpers

8.2.8 Building a Simple Photo Gallery in ASP.NET MVC Framework

See document: BuildingASimplePhotoGalleryInASPNETMVCFramework.aspx

8.2.9 25+ Best ASP.NET MVC Tutorials and Articles

See document: 25-plus-best-asp-net-mvc-tutorials-and-articles

8.2.10 A Guide to Learning ASP.NET MVC Release Candidate 1

See document: a-guide-to-learning-asp.net-mvc-release-candidate-1.aspx

8.2.11 Creating a Tag Cloud using ASP.NET MVC and the Entity Framework

See document: Creating-a-Tag-Cloud-using-ASP.NET-MVC-and-the-Entity-Framework

8.2.12 Creating an ASP.NET MVC 2 Controller Factory with Ninject

See document: creating-aspnet-mvc-2-controller.html

8.2.13 How to use Ninject 2 with ASP.NET MVC

See document: how-to-use-ninject-2-with-asp.net-mvc.aspx

8.2.14 ASP.NET MVC 2

See document: dd394709.aspx

8.3 Projects

Some real world project.

8.3.1 Oxite

See document: oxite

Blog engine built on ASP.NET MVC

8.3.2 MVC StoreFront

See document: mvc-storefront-part-1

Page 121: ASP.Net MVC 4 All

ASP.Net MVC 4 all - E J Hernández Valdelamar

June, 2010

Rob Conery has been documenting the design and creation of a storefront using the MVC Framework along with

Agile coding practices such as test- driven development and common patterns such as the Repository Pattern.

8.3.3 Blogging Engine

See document: 1538_Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_1

Keyvan Nayyeri has a multi-part series on building a Blog Engine with ASP.NET MVC. Blog Engine creation seems to

be a popular way for people to demonstrate technology and it does it effectively.

8.3.4 Kigg - The Digg Clone

See document: Kigg

This Digg clone is a very good implementation and use of the MVC Framework.

8.3.5 Yonkly

See document: yonkly

Yonkly is an open source (well, not any more) twitter clone application built with ASP.net MVC. Yonkly provides the

functionalities of twitter and some additional features such as threaded messages and also provides integration

with twitter.

8.3.6 Ninject

See document: ninject.org

Ninject is a lightning-fast, ultra- lightweight dependency injector for .NET applications. It helps you split your

application into a collection of loosely-coupled, highly-cohesive pieces, and then glue them back together in a

flexible manner. By using Ninject to support your software's architecture, your code will become easier to write,

reuse, test, and modify.

8.3.6.1 In codeplex

See document: ninject.codeplex.com