以及自己学ASP.NET MVC之三:完整的ASP.NET MVC程序-PartyInvites

摘要:

当马上首稿子中,我将以一个事例中实际上地显示MVC。

场景

倘若一个恋人控制举办一个新春佳节晚会,她请自己创建一个所以来邀请对象参加晚会的WEB程序。她提出了季独注意的求:

  • 一个首页显示是晚会
  • 一个表单用来交给报名
  • 证表单内容,成功后显示谢谢页面
  • 完成后被主人发送申请邮件

添加Model类GuestResponse

别程序都应是坐多少为核心。因此,首先,在工程外加加Domain Model。
在工程根部创建Model文件夹。
当Model文件夹内创建GuestResponse.cs代码文件。
修改GustResponse代码。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 
 6 namespace PartyInvite.Models
 7 {
 8     public class GuestResponse
 9     {
10         public string Name { get; set; }
11         public string Email { get; set; }
12         public string Phone { get; set; }
13         public bool? WillAttend { get; set; }
14     }
15 }

修改Index视图。

自将打算用Home/Index作为首页,修改Index视图。

 1 @{
 2     Layout = null;
 3 }
 4 
 5 <!DOCTYPE html>
 6 
 7 <html>
 8 <head>
 9     <meta name="viewport" content="width=device-width" />
10     <title>Index</title>
11 </head>
12 <body>
13     <div> 
14        @ViewBag.Greeting World (from the view)
15         <p>
16             We're going to have an exciting party.<br />
17             (To do: sell it better. Add pictures or something.)
18         </p>
19         @Html.ActionLink("RSVP Now", "RsvpForm")
20     </div>
21 </body>
22 </html>

实施顺序,在浏览器被取得周转结果。

图片 1

当页面底部出现了一个“RSVP
Now链接”,这个链接是措施Html.ActionLink得到的。

将鼠标移到该链接上,可以望链接指向了/Home/RsvpForm链接。

图片 2

为工程指定默认页面

鼠标右键工程PartyInvites,在弹出的菜单中选择Properties。在Web选项卡中摘“Specific
page”,在输入框中输入Home/Index。

图片 3

 

为RSVP添加Action和视图

返回HomeController,添加Action。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6 
 7 namespace PartyInvites.Controllers
 8 {
 9     public class HomeController : Controller
10     {
11         // GET: Home
12         public ViewResult Index()
13         {
14             int hour = System.DateTime.Now.Hour;
15             ViewBag.Greeting = hour < 12 ? "Good Moring" : "Good Afternoon";
16             return View();
17         }
18 
19         public ViewResult RsvpForm()
20         {
21             return View();
22        }
23     }
24 }

为RsvpForm这个Action添加视图。

 图片 4

模板选择“Empty”,Model class选择刚刚创立的Domain
Model类GuestResponse。点击“Add”按钮添加。

修改添加的视图RsvpForm.cshtml。

 1 @model PartyInvite.Models.GuestResponse
 2 
 3 @{
 4     Layout = null;
 5 }
 6 
 7 <!DOCTYPE html>
 8 
 9 <html>
10 <head>
11     <meta name="viewport" content="width=device-width" />
12     <title>RsvpForm</title>
13 </head>
14 <body>
15     @using (Html.BeginForm())
16     {
17         <p>Your name: @Html.TextBoxFor(x => x.Name) </p>
18         <p>Your email: @Html.TextBoxFor(x => x.Email)</p>
19         <p>Your phone: @Html.TextBoxFor(x => x.Phone)</p>
20         <p>
21             Will you attend?
22             @Html.DropDownListFor(x => x.WillAttend, new[] {
23                                       new SelectListItem() {Text = "Yes, I'll be there",
24                                       Value = bool.TrueString},
25                                       new SelectListItem() {Text = "No, I can't come",
26                                       Value = bool.FalseString}
27                                 }, "Choose an option")
28         </p>
29         <input type="submit" value="Submit RSVP" />
30     }
31 </body>
32 </html>

一些解释:

@model PartyInvite.Models.GuestResponse:此视图以GuestResponse类作为它的Model。

@using (Html.BeginForm()) {}: 调用Html帮助类,创建一个表单,大括号里面的内容是表单内容。

@Html.TextBoxFor、@Html.DropDownListFor:调用Html帮助类,传入lamda表达式,为表单创建输入HTML元素。

执行程序,在浏览器中得到的Index页面中点击“RSVP Now”链接,得到下面的页面。

处理表单

本人还尚未报告MVC当表单提交到劳动器端的上我响应做什么。按照目前之情形,点击提交按钮只是清空你才填写的音信。这是因表单提交到Home控制器的RsvpForm行为方式,这个法子只有是告MVC再次呈现是视图。

博和处理提交的表单数据,我将利用一个聪明的章程。我用助长第二只RsvpForm行为方式来做下的作业:

 

  • 一个法响应HTTP
    GET请求。GET请求是于用户点击一个链接时浏览器发出的。当用户率先涂鸦看/Home/RsvpForm的早晚显得起空白表单调用此版本的方法。

  • 一个应HTTP提交请求的点子:默认的,使用Html.BeginForm()方法展现的表单由浏览器提交一个POST请求。这个本的一言一行艺术负责取提交数据以及控制将到数量做啊业务。

 

以分别的C#道中拍卖GET和POST请求于自家之控制器打开变得简洁,因为少独艺术有例外之权责。两个表现艺术还由同的URL激活,但是MVC根据拍卖的是一个GET还是POST请求保管合适的办法吃调用。下面是改后的HomeController类。

 1 using PartyInvite.Models;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Mvc;
 7 
 8 namespace PartyInvites.Controllers
 9 {
10     public class HomeController : Controller
11     {
12         public ViewResult Index()
13         {
14             int hour = System.DateTime.Now.Hour;
15             ViewBag.Greeting = hour < 12 ? "Good Moring" : "Good Afternoon";
16             return View();
17         }
18 
19         [HttpGet]
20         public ViewResult RsvpForm()
21         {
22             return View();
23         }
24 
25         [HttpPost]
26         public ViewResult RsvpForm(GuestResponse guestResponse)
27         {
28             // TODO: Email response to the party organizer
29             return View("Thanks", guestResponse);
30         }
31     }
32 }

我当今天之RsvpForm行为方式齐加加了HttpGet特性。这告诉MVC这个点子应该只用来处理GET请求。然后上加一个重载版本的RsvpForm,传入一个GustResponse参数,用HttpPost特性修饰。这个特点告诉MVC这个心之不二法门处理Post请求。

展现其他视图

老二只重载的RsvpForm行为艺术为展示了哪些告诉MVC为请的应呈现一个切实的视图,而不是默认的视图,这是系的语句:

return View("Thanks", guestResponse);

当即调用View方法告诉MVC寻找并呈现一个名被“Thanks”的视图,并传递GuestResponse对象吃此视图。

当Views/Home文件夹着创造Thanks视图。

图片 5

修改视图代码:

@model PartyInvite.Models.GuestResponse

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Thanks</title>
</head>
<body>
    <div>
        <h1>Thank you, @Model.Name!</h1>
        <div>
            @if (Model.WillAttend == true)
            {
                <p>It's great that you're coming. The drinks are already in the fridge!</p>
            }
            else {
                @:Sorry to hear that you can't make it, but thanks for letting us know.
        }
        </div>
    </div>
</body>
</html>

根据自己传给视图方法RsvpForm的参数GuestResponse对象属性值,这个Thanks视图使用Razor展示内容。Razor表达式@Model引用我写好的Domain
Model类型,得到目标的属性值Model.Name。

实践顺序,在RsvpForm表单中填入数据,点击“Submit”
按钮,跳反到Thanks页面。

图片 6

长求证

自身现而为本人之应用程序添加验证。没有认证,用户或输入无意义的多少或者甚至提交空的表单。在MVC应用程序里,把Domain
Model(域模型)应用及说明,而无是用户接口。这代表自己好在一个地方定义说明准则,在模块类吃使用的应用程序里其他地方都见效。ASP.NET
MVC支持定义System.ComponentModel.DataAnnotations名称空间的表征声明式验证规则,意味着验证约束下标准的C#特性来表述。

修改GuestResponse类。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel.DataAnnotations;
 4 using System.Linq;
 5 using System.Web;
 6 
 7 namespace PartyInvite.Models
 8 {
 9     public class GuestResponse
10     {
11         [Required(ErrorMessage = "Please enter your name")]
12         public string Name { get; set; }
13         [Required(ErrorMessage = "Please enter your email address")]
14         [RegularExpression(".+\\@.+\\..+", ErrorMessage = "Please enter a valid email address")]
15         public string Email { get; set; }
16         [Required(ErrorMessage = "Please enter your phone number")]
17         public string Phone { get; set; }
18         [Required(ErrorMessage = "Please specify whether you'll attend")]
19         public bool? WillAttend { get; set; }
20     }
21 }

证明代码用粗体字显示。MVC在模型-绑定过程遭到机动探测特性并应用他们说明数据。

每当Controller类里,我下ModelState.IsValid属性检验是不是发生证实问题。下面是改后底Controller类RsvpForm方法。

 1         [HttpPost]
 2         public ViewResult RsvpForm(GuestResponse guestResponse)
 3         {
 4             if (ModelState.IsValid)
 5             {
 6                 return View("Thanks", guestResponse);
 7             }
 8             else
 9             {
10                 return View();
11             }
12         }

倘没征错误,我报告MVC呈现Thanks视图,像自己前面那么。如果产生证实错误,我调用不含参数的View方法重新呈现是表单。

单纯是展示这表单而不示错误信息是没有呀帮助的-我还需要吗用户提供有不当提示信息以及为何自己无可知收获表单的交由数据。我以RsvpForm视图里以Html.ValidationSummary帮助方法来达到这个目的。下面是改后底RsvpForm视图。

如若无不当,Html.ValidationSummary方法在表单内创造一个掩蔽的列表项作为占位符。MVC使得占位符变得可见并以定义在验证属性之荒唐信息显示在上头。

付给空白的RsvpForm表单,得到下面的周转结果。

图片 7

拿无见面让用户展示Thanks视图,直到所有的以在GuestResponse类的征约束都于满足。注意输入到于视图被展现的当儿,表单的多寡为保留了并跟认证摘要信息相同从再显示。

高亮显示非法输入字段

HTML帮助方法创建文本框、下拉框和外的因素,这些元素来备的得用于模型绑定的性状。相同的保留用户输入到表单的数据机制同被用来高亮显示验证失败的字段。

当一个模类属性验证失败了,HTML帮助方法以发多少不同的HTML。

比如说,下面是调用Html.TextBoxFor(x=>x.Name)方法后,验证没有错的文本框:

<input data-val=”true” data-val-required=”Please enter your
name” id=”Name” name=”Name” type=”text” value=”” />

下是调用相同方式后,用户并未输入值(这是一个认证错误,因为自身于Name属性运用了Request特性)的文本框:
<input class=”input-validation-error” data-val=”true”
data-val-required=”Please enter your name” id=”Name” name=”Name”
type=”text” value=”” />
救助方法上加了一个名称为input-validation-error的类到元素上。我得以应用是特点,创建一个带有这个css类样式的样式表。

每当绝望目录下加加Content文件夹,在Content文件夹内上加样式表文件Styles.css。

1 .field-validation-error {color: #f00;}
2 .field-validation-valid { display: none;}
3 .input-validation-error { border: 1px solid #f00; background-color:#fee; }
4 .validation-summary-errors { font-weight: bold; color: #f00;}
5 .validation-summary-valid { display: none;}

改RsvpForm视图,添加样式表引用。

 1 @model PartyInvite.Models.GuestResponse
 2 
 3 @{
 4     Layout = null;
 5 }
 6 
 7 <!DOCTYPE html>
 8 
 9 <html>
10 <head>
11     <meta name="viewport" content="width=device-width" />
12     <link rel="stylesheet" type="text/css" href="~/Content/Styles.css" />
13     <title>RsvpForm</title>
14 </head>
15 <body>
16     @using (Html.BeginForm())
17     {
18         @Html.ValidationSummary()
19         <p>Your name: @Html.TextBoxFor(x => x.Name) </p>
20         <p>Your email: @Html.TextBoxFor(x => x.Email)</p>
21         <p>Your phone: @Html.TextBoxFor(x => x.Phone)</p>
22         <p>
23             Will you attend?
24             @Html.DropDownListFor(x => x.WillAttend, new[] {
25                                     new SelectListItem() { Text = "Yes, I'll be there", Value = bool.TrueString },
26                                     new SelectListItem() { Text = "No, I can't come", Value = bool.FalseString }
27                                 }, "Choose an option")
28         </p>
29         <input type="submit" value="Submit RSVP" />
30     }
31 </body>
32 </html>

当RsvpForm表单输入错误的时段,页面将显得如下所示、

图片 8

受视图添加样式

主导的应用程序功能就做好了-除了发送邮件,但是完全的外观非常简陋。

此我下Bootstrap库,这是先是Twitter公司开发的现在用得可怜常见的一个CSS库。

利用NutGet导入Bootstrap库。Bootstrap库的CSS文件将导入到Content文件夹下,JavaScript文件将导入到Scripts文件夹下。

修改Index视图。

 1 @{
 2     Layout = null;
 3 }
 4 
 5 <!DOCTYPE html>
 6 
 7 <html>
 8 <head>
 9     <meta name="viewport" content="width=device-width" />
10     <link href="~/Content/bootstrap.css" rel="stylesheet" />
11     <link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
12     <title>Index</title>
13     <style>
14         .btn a {
15             color: white;
16             text-decoration: none;
17         }
18 
19         body {
20             background-color: #F1F1F1;
21         }
22     </style>
23 </head>
24 <body>
25     <div class="text-center">
26         <h2>We're going to have an exciting party!</h2>
27         <h3>And you are invited</h3>
28         <div class="btn btn-success">
29             @Html.ActionLink("RSVP Now", "RsvpForm")
30         </div>
31     </div>
32 </body>
33 </html>

修改RsvpForm视图。

 1 @model PartyInvite.Models.GuestResponse
 2 
 3 @{
 4     Layout = null;
 5 }
 6 
 7 <!DOCTYPE html>
 8 
 9 <html>
10 <head>
11     <meta name="viewport" content="width=device-width" />
12     <link href="~/Content/bootstrap.css" rel="stylesheet" />
13     <link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
14     <title>RsvpForm</title>
15 </head>
16 <body>
17     <div class="panel panel-success">
18         <div class="panel-heading text-center"><h4>RSVP</h4></div>
19         <div class="panel-body">
20             @using (Html.BeginForm())
21             {
22                 @Html.ValidationSummary()
23                 <div class="form-group">
24                     <label>Your name:</label>@Html.TextBoxFor(x => x.Name)
25                 </div>
26                 <div class="form-group">
27                     <label>Your Email:</label> @Html.TextBoxFor(x => x.Email)
28                 </div>
29                 <div class="form-group">
30                     <label>Your Phone:</label> @Html.TextBoxFor(x => x.Phone)
31                 </div>
32                 <div class="form-group">
33                     <label>
34                         Will you attend?
35                     </label>
36                     @Html.DropDownListFor(x => x.WillAttend,
37                     new[] {
38                        new SelectListItem() { Text="Yes, I will be there" , Value = bool.TrueString },
39                        new SelectListItem() { Text = "Yes, I will be there", Value = bool.TrueString }
40                     }, "Choose an option")
41                 </div>
42                 <div class="text-center">
43                     <input class="btn btn-success" type="submit"
44                            value="Submit RSVP" />
45                 </div>
46             }
47         </div>
48     </div>
49 </body>
50 </html>

修改Thanks视图。

 1 @model PartyInvite.Models.GuestResponse
 2 
 3 @{
 4     Layout = null;
 5 }
 6 
 7 <!DOCTYPE html>
 8 
 9 <html>
10 <head>
11     <meta name="viewport" content="width=device-width" />
12     <link href="~/Content/bootstrap.css" rel="stylesheet" />
13     <link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
14     <title>Thanks</title>
15     <style>
16         body {
17             background-color: #F1F1F1;
18         }
19     </style>
20 </head>
21 <body>
22     <div class="text-center">
23         <h1>Thank you, @Model.Name!</h1>
24         <div class="lead">
25             @if (Model.WillAttend == true)
26             {
27                 <p>It's great that you're coming. The drinks are already in the fridge!</p>
28             }
29             else {
30                 @:Sorry to hear that you can't make it, but thanks for letting us know.
31         }
32         </div>
33     </div>
34 </body>
35 </html>

运转程序,在浏览器中得到周转结果。

Index页面:

图片 9

RsvpForm页面:

 图片 10

Thanks页面:

图片 11

成功这个事例

本身的例子的最后一个需是深受晚会主办者发送提交邮件。

修改Thanks视图,添加发送邮件代码。

 1 @model PartyInvite.Models.GuestResponse
 2 
 3 @{
 4     Layout = null;
 5 }
 6 
 7 <!DOCTYPE html>
 8 
 9 <html>
10 <head>
11     <meta name="viewport" content="width=device-width" />
12     <link href="~/Content/bootstrap.css" rel="stylesheet" />
13     <link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
14     <title>Thanks</title>
15     <style>
16         body {
17             background-color: #F1F1F1;
18         }
19     </style>
20 </head>
21 <body>
22     @{
23         try
24         {
25             WebMail.SmtpServer = "smtp.example.com";
26             WebMail.SmtpPort = 25;
27             WebMail.EnableSsl = true;
28             WebMail.UserName = "example@163.com";
29             WebMail.Password = "password";
30             WebMail.From = "example@163.com";
31             WebMail.Send("example@163.com", "RSVP Notification", Model.Name + " is " + ((Model.WillAttend ?? false) ? "" : "not") + "attending");
32         }
33         catch (Exception e)
34         {
35             <b>
36                 Sorry - we couldn't send the email to confirm your RSVP.
37             </b>
38         }
39     }
40     <div class="text-center">
41         <h1>Thank you, @Model.Name!</h1>
42         <div class="lead">
43             @if (Model.WillAttend == true)
44             {
45                 <p>It's great that you're coming. The drinks are already in the fridge!</p>
46             }
47             else
48             {
49                 @:Sorry to hear that you can't make it, but thanks for letting us know.
50         }
51         </div>
52     </div>
53 </body>
54 </html>

 

相关文章