ASP.NET MVC IN ACTION with a Sample Application – Part 3

Vasanthmvp
Posted by in ASP.NET MVC category on for Beginner level | Points: 250 | Views : 9102 red flag
Rating: 5 out of 5  
 1 vote(s)

In this article, our goal is to demonstrate MVC in action by creating a sample data entry application.

Introduction

In this article, our goal is to demonstrate MVC in action by creating a sample data entry application.

MVC Overview:

          The ASP.NET MVC framework is an application pattern that provides an alternative to the ASP.NET Web forms for creating web applications.  A basic introduction to ASP.NET MVC and its features were discussed in the first two articles - http://www.dotnetfunda.com/articles/article2092-introduction-to-aspnet-mvc-csharp-part-1.aspx.

http://www.dotnetfunda.com/articles/article2100-mvc-application-structure-components-functionality-with-an-example-pa.aspx

Description: 

Let us move in to our article.

Requirement: Create an application to host about a social event and that allows the invitees to electronically respond - RSVP (Usually it is used on an invitation requesting for a response about the event). The features it includes are:

1.    1.  Home page which includes all the details about the event

2.    2.  A form that can be used to RSVP

3.    3.  A Thank you page

4.    4.  RSVPs of invitees are mailed to the party host after completion

asA  Application reference: Pro ASP.NET MVC Book

Creating a home page is all about adding HTML controls to a view as what we had covered in the earlier article. For a better lay out we can add a few HTML controls. 

First add a Homecontroller.cs as

public ViewResult Index() {
          int hour = DateTime.Now.Hour,
          string Wish = hour < 12 ? “Good Morning” : “Good Afternoon”;
          ViewDate[“greeting”] = Wish;
          return View();
}

Adding a view to the index method
Index.cshtml

@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
          <title> Index </title>
</head>
<body>
<div> @ViewBag.Greeting, world (from the view) </div>
<p> We’re going to have an exciting party. <br />
(To do: Sell it better, Add pictures or something.) </p>
</body>
</html>


Now let’s move on to how a model looks like and we shall work on it practically into our application.

Model : In MVC, m stands for model and it is the most important part of the application. The model is the representation of the real world(C#) objects, processes, rules, etc., also called the domain of the application. Model also called domain model are written with objects which we manipulate them using methods, expose them, and finally controllers and view are used to display the content consistently.

Similar to data contracts or DTO’s with properties or data members of a class we can represent a model in the form of a domain class. In our application, we create a GuestResponse Domain class. This will be responsible for storing, validating and confirming RSVP.

Add a Model : Following the MVC Convention, all the model classes are included under the ~/Models folder of the application. Hence we add a new class GuestResponse.cs with the following properties under models folder.

 
Pulic class GuestResponse {
   Public string Name { get; set; }
   Public string Email { get; set; }
   Public string Phone { get; set; }
   Public bool? WillAttend { get; set; }
}

Note : WillAttend property is nullable, it can be true false and null.
Linking Action Methods : Now our application goal is to include a RSVP form, so we shall add a link from our home page using @Html.ActionLink method.
Index.cshtml : beneath the paragraph tag we will add a link.

<p>
We’re going to have an exciting party. <br />
(To do: Sell it better, Add pictures or something.) </p>
@Html.ActionLink(“RSVP Now”,”RsvpForm”);
</body>
</html>

Html.ActionLink is an html helper method. MVC Framework comes with a collection of built in helper methods that are convenient for rendering HTML Links, text inputs, check boxes, selections, and even custom controls. The ActionLink method takes two parameters, of which first one is the text to be rendered on the link and second is the action to be perform when user clicks the link. We shall see more on HTML helper methods later on.


If you hover the mouse on link, you can see that url pointing to http://yourserver/Home/RsvpForm which means that ActionLink method has inspected our applications URL routing configuration and found that /Home/RsvpForm is the url for the action RsvpForm(2nd parameter) on HomeController. Unlike traditional ASP.Net’s Url doesnot correspond to the physical files but, MVC translates these url’s into actions. Now, if we click on the link it reports 404 error since we did not create an action method RsvpForm yet in the HomeController.

Creating an action method in HomeControlle.cs
Public ViewResult Index() {
int hour = DateTime.Now.Hour,
          string Wish = hour < 12 ? “Good Morning” : “Good Afternoon”;
          ViewDate[“greeting”] = Wish;
          return View();
}
Public ViewResult RsvpForm() {
Return view();
}

Adding a strongly typed view:

Now, we want the invitees response and their details be sent to party host. For which, we create a RsvpForm view. We will a view for our RsvpForm action method but slight different from our previous add view process i.e., to add a strongly typed view. As I had mentioned it earlier what a domain model is, we want to associate the domain model with objects to our RsvpForm. A strongly typed view is intended to render a specific domain type, and by specifying the domain that we want to work with (GuestResponse in our example) MVC will create intellisense and make it easier.

Note: Make sure that before you add a strongly typed view, your application is compiled well because MVC has to detect it under model class while adding a strongly typed view.

Right click on RsvpForm action method and select add view to create the view.


In the pop up, check the create a strongly typed view option and select the model class GuestResponse.cs, unselect the Use a layout or master page, and view engine as Razor and click on Add button.

You can see an RsvpForm.cshtml is being created with razor block layout = null and basic html document tags. Emphasizing, basically we want to set the invitees opinion and details to the domain properties. So, what we do is Unlike in traditional Asp.Net, adding a few server controls with runat = “server” to our aspx page and access its values from code behind, set to a datacontract and move on.

We will associate our GuestResponse domain properties to edit them to the html controls of our RsvpForm view and make it an html form, which serves our MVC architecture motto.

 
RsvpForm.cshtml :
@{
        Layout = null;
}
<!Doctype html>
<html>
<head> <title> Rsvp Form </title> </head>
<body>
      @Using (Html.BeginForm()) {
           <p> Your Name: @Html.TextBoxFor( x => x.Name) </p>
           <p> Your Email: @Html.TextBoxFor( x => x.Email) </p>
           <p> Your phone: @Html.TextBoxFor( x => x.Phone) </p>
           <p> Will You attend?
    @Html.DropDownListFor(x => x.WillAttend, new[] { New SelectListItem() {Text = “Yes, I’ll be there”, Value = bool.TrueString },
              New SelectListItem() {Text = “No, I can’t come”, Value = bool.FalseString }, “Choose an option”)
     }
</p>
<input type=”submit” value=”Submit RSVP” />
</body>
</html>

For each property of GuestResponse model class, we use a Html helper method to render a suitable html input control. These html helper method let you select the property that the input element want to correspond to using a lambda expression.

For ex : @Html.TextBoxFor( x => x.Phone) The html helper method generates a html line of code that creates an input element with type = text, id and name = Phone as follows:

<input type=”text” id=”Phone” runat=”Phone” id=”Phone” value=”” />

Since we have created the strongly typed view with GuestResponse model class, InselliSense provides us a handy feature.

If we already know the property name exactly, we can use the helper methods without lambda expressions like:

@Html.TextBox(“Email”);


We see another Html helper method Html.BeginForm(), which generates a html form element to post back to the action method. Since we have not passed any parameters, it assumes to post back to the same URL. Its good to wrap this inside C# using statement because using immediately disposes the objects after their scope, this is useful when we include database connections here they get immediately disposed after their use. Since here is Html.BeginForm helper class, it closes the form when it goes out of the scope. Hence, Html.BeginForm method generates a html form for our Home/RsvpForm action method as described:

<form action=”/Home/RsvpForm” method=”post” />     </form>

Note : In the traditional asp.net WebForms, we can find only one server side form per aspx page like <form runat=”server”   />. It includes all the view state and postback information of the page. But, in MVC there are no hidden form elements, no view states, etc., Since they are all simple HTML you can have more than one form.

Now, build the application and run it. On click of the Rsvp link, we get navigated to Rsvp View as shown:



Handling Forms:

In the traditional ASP.NET Web Forms, we fill out the form and click on submit button. The input values can be accessed from code behind and processed for further actions. Here, in our MVC application we will develop a similar kind of thing. Till now, we went through developing views, but what if we click on submit RSVP button.  You can observe that each time when we click on the submit button Home/RsvpForm is rendered fresh. Also, if you have entered any values into the text boxes and click submit they get empty because we have not written anything yet to be connected with the button to perform an action unlike we write a OnClick event in asp.net web forms. When we click on Submit button, since the @Html.Begin form generates a html form it calls back the same Home/RsvpForm action method and it returns a view and the same page is rendered. Hence each time the page refreshes and inputs get empty. So, our problem is the same RsvpForm action method is being called for both rendering the view and while submit event. In difference to web forms, when no event method is written, the form is not submitted and the input values remains persisted. Now, we are going to achieve the same in MVC.

We are going to differentiate the process of :

1.    Rendering the view page i.e., HTTP GET request method

2.    Submitting by the browser i.e., HTTP Post request method

using method overloading.

Note :

* Http Get request is what a browser requests for a page when someone clicks on a link or a user enters a url for a page. This get method will be responsible for fetching the page and display it.

* Http Post request is Forms are submitted by the browser as post request. This post method will be responsible to make use of submitted data and perform further action.

Hence, we create another RsvpForm action method as post method. These methods are invoked from the same URL, but MVC makes sure of calling an appropriate method based on http get or post request.

Adding an action method to HomeController:
Public class HomeController : Contoller {
Public ViewResult Index() {
int hour = DateTime.Now.Hour,
          string Wish = hour < 12 ? “GoodMorning” : “Good Afternoon”;
          ViewDate[“greeting”] = Wish;
          return View();
}
[HttpGet]
Public ViewResult RsvpForm() {
Return View();
}
 
Include the System.Net.Mail; namespace.
[HttpPost]
Public ViewResult RsvpForm(GuestResponse guestResponse) {
MailMessage Mail1 = new MailMessage();
SmtpClient smtpServer= new SmtpClient("smtp.gmail.com");
 
Mail1.From = new MailAddress("myemail@gmail.com");
Mail1.To.Add(guestResponse. Email);
Mail1.Subject = "Thanks for Responding";
if(guestResponse.WillAttend == true)
Mail1.Body = "Hey !! It’s great that you are coming. Let’s hang over tonight. ";
else
Mail1. Body = “Sorry to hear that you can’t make it. But thanks for letting us know. Great Day.”;
smtpServer.Send(mail);
 
MailMessage Mail2 = new MailMessage();
 
Mail2.From = new MailAddress("myemail@gmail.com");
Mail2.To.Add(“myemail@gmail.com);
Mail2.Subject = "Invitee Response";
if(guestResponse.WillAttend)
Mail2.Body = guestResponse.Name + "is attending. Contact him at " + guestResponse.Email;
else
Mail2.Body = guestResponse. Name +  can’t make it.”;
smtpServer.Send(mail);
return View(“Thanks”, guestResponse);
         }
}                                  

Using Model Binding :         

The first RsvpForm action generates & renders the view as before. The second overload action method will be invoked in response to a Http Response request with GuestResponse C# object. But, how are these connected ?? It is through Model Binding. Model binding is an extremely useful MVC feature whereby incoming data is parsed and key/value pairs are used to populate properties of domain model types. This process is opposite to using Html Helper methods. It means that, when creating the form data to send to the client, we generated html input elements where the values of the id and name attributes are derived from the name of the domain model properties as described earlier:

Public string Name { get; set; } is used in html helper method to set the form data Name as

@Html.TextBoxFor( x => x.Name}. This helper method generate a input element as <input type=”text” id=”Name” name=”Name” value=”” />

In contrast, with Model Binding, names of the input elements are used to set the values of the properties in an instance of the model class, which is then passed to the POST enabled action method. Model Binding lets us work with C# objects rather than Request.Form[] and Request.QueryString[] values. The GuestResponse object passed as parameter to the POST action method automatically polulates the data with the data from the form fields.

Next, we send two emails in the POST method. One to the participating invitee with a message and other to the Pary host with the invitee name,  response and  email id. Now, we are returning a parameterized View(“Thanks”,guestResponse).

This view method tells the MVC to search for a view called Thanks and pass our GuestResponse model object to the view. To add a view, right click inside one of the action methods of HomeController & select add View. Set the properties as shown and add a strongly typed view with GuestRespones as model class.


Now, the Thanks View is edited as 
@model PartyInvites.Model.GuestResponse
@{
Layout = null;
}
<!—DOCTYPE html>
<html>
<head> <title> Thanks </title> </head>
<body>
       <div>
                     <h1> Thanks You, @Model.Name </h1>
           @if(Model.WillAttend == true) {
   @: It’s great that you are coming. The drinks are already in the firidge.
} else {
  @: Sorry to hear that you can’t make it. But thanks for letting us know.
}
       </div>
</body>
</html>

The Thanks View uses the Razor view to display the content based on the values of the Guest Response properties that we pass to the View method in the RsvpForm action method. The @model specified the model that the view is strongly typed with. The properties can be accessed through Mode.PropertyName like Model.Name in our application.


Now, the application is ready to be hosted. Click on the Rsvp link, you get redirected to RsvpForm view. Fill the form field and submit, then a ThankYou page appears.

Conclusion

In the current article we had seen how an MVC application practically looks like with an sample application and more on Model and its usage,etc.,

Reference

http://www.asp.net/mvc, ASP.NET MVC Framework Book


Page copy protected against web site content infringement by Copyscape

About the Author

Vasanthmvp
Full Name: VASANTH KUMAR
Member Level:
Member Status: Member
Member Since: 6/26/2012 12:13:54 AM
Country: India
Awesome Coding !! :)
http://www.dotnetfunda.com
Started my journey with what is .Net on 30-07-2012 and pretty excited to learn & share it on DotNetFunda since 15-08-2012. :) Exploring more & more :)

Login to vote for this post.

Comments or Responses

Posted by: Sheonarayan on: 1/28/2013 | Points: 25
Good job, keep it up!
Posted by: Vasanthmvp on: 1/29/2013 | Points: 25
Thank You Sir.

Login to post response

Comment using Facebook(Author doesn't get notification)