ASP.NET MVC 开发实例(一)

ASP.NET MVC 开发实例(一)

近几年前端发展很快,大有不需要后端之趋势。node.js+webpack我现在也有在观望学习中,的确,很酷。但是我并没有进行产品开发,因为这种东西一投入,说不定马上就有一个更酷的框架出来。学习框架和你做投资一样,都需要成本。新框架带来了一些新技术,也带来了新问题。但由于是开源的关系,所有的问题都很快得到解决。同时,需求不同也就造就今天框架盛行的局面。没有完美的架构,只有适合的架构,如果你想要有一个完全匹配你需求的框架,那么就自己写一个。很多有实力的公司就是这么做的。

其实,我更乐意做的事,就是 在原有的技术上,兼容现在流行的MV*前端框架,以达到迅速开发的目的,如果产品页需要SEO,那么回到C#,用传统的后端对页面进行渲染。要做到数据灵活绑定,游刃有余。

我希望这一系列的教材,是从ASP.NET MVC入门开始,再开发一套小型的商城网站,最后写一套属于自己的MVC架构出来。这是一个上十万字的大工程,不过如果能在业余时间做出来,我会很佩服我自己的。准备了两套入门方案,一套建立Empty模板,为注册会员代码。一套为自动生成代码的留言板方案,然后修改。以此来增强入门体验。

从现在开始吧,打开Visual Studio 2015,先来做个例子。

下面是一个用户管理的实例,这个实例没有关联到任何数据库,当然也不会有Identity,下面这个实例只是让你基本的了解一下MVC的基本操作概念。(本例子参考了《精通ASP.NET MVC5》,书中第二章:第一个MVC应用程序。)

新建项目,在已安装-模板里面选择Web,创建一个ASP.NET Web 应用程序,如下图。本例命名为alexzeng,当然你可以改为你喜欢的任何名字,不违背命名规则就可以。

创建一个ASP.NET Web 应用程序

在弹出来的新建ASP.NET 项目里面选择一个Empty模板,为以下添加文件夹和核心引用点击MVC。

选择Empty模板

然后在解决方案资源管理器的窗口里面,找到Controllers,右击新建一个新的控制器,如下图,选择MVC 5控制器-空。命名为HomeController.cs 。

默认代码如下:

using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace alexzengnet.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return View();
        }


    }
}

现在我们还运行不了这个网站,稍微改一下代码:

 public string Index()
        {
            return "<h1>欢迎光临</h1>";
        }

按一下F5,可以开始浏览到网站了,一个基于ASP.NET框架的网站基本成立了。

再把代码恢复成默认的样子,对着Index右击鼠标,新建视图,在弹出来的窗口,按默认值即可。

将代码修改成下面的样子,运行一下,是不是和刚才一样


@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div> 
        <h1>欢迎光临!</h1>
    </div>
</body>
</html>

回到HomeController.cs,我们给代码添加一点动态,在这里我们使用的是ViewBag。

将数据传给视图的一种方式是使用了ViewBag, ViewBag是一个动态的对象,可以赋予它任何属性。

下面的例子就是演示如何使用ViewBag。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace alexzengnet.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            int hour = DateTime.Now.Hour;
            ViewBag.SayHi=hour<12?"早上好":"下午好";
            return View();
        }


    }
}

再打开视图文件:Index.cshtml,修改一下代码:


@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div> 
        <h1>欢迎光临!</h1>
        <p>@ViewBag.SayHi</p>
        @Html.ActionLink("注册会员","REG")
    </div>
</body>
</html>

运行一下试试,它会根据你当前的时间显示上午好还是下午好,这是一个最简单的MVC程序。下面我们将继续完善它,我们会结合流行的Bootstrap ,做一个简单的注册会员程序。

现在,首先我们先来安装Bootstrap

打开工具菜单,点击NuGet程序包管理器里面的程序包管理器控制台。它是一个PowerShell的运行环境,在控制台里面输入(注意,区分大小写):

Install-Package -version 3.0.0 bootstrap

完成了安装程序后会有提示:已将“bootstrap 3.0.0”成功安装到 alexzengnet。

我在制作网页的时候,通常是先做PS文件,然后通过PS做成html,最后将html分拆成我所需要的cshtml。下面就是加载了bootstrap 的注册页面。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <meta charset="utf-8" />
    <link href="Content/bootstrap.min.css" rel="stylesheet">
    <script src="Scripts/jquery-1.9.0.min.js"></script>
    <script src="Scripts/jquery-1.9.0.min.js"></script>
    <style>
    body {
    padding-top:50px;  
    color:#FFF; background:#444;
    }
    div {margin:5px auto;}
    h1 {
    color: #fff;
    }
    #content{
    width:100%;
    min-height:600px;
    background:#444;
    padding-top:20px;
    color:#FFF;
    }
    .register{
    padding: 20px;
    font-weight:700;
    border:#FFF solid 1px;
    -moz-border-radius: 10px;      /* Gecko browsers */
    -webkit-border-radius: 10px;   /* Webkit browsers */
    border-radius:10px;            /* W3C syntax */
    }
    .col-sm-3{
        line-height:48px;
    }
    </style>
</head>
<body>
    <div id="content">
        <div class="container">
            <form>
                <div class="row">
                    <h1 class="col-md-6 col-md-offset-3 col-xs-10 col-xs-offset-1 page_title ">注册</h1>
                </div>
                <div class="col-md-6 col-md-offset-3 col-xs-10 col-xs-offset-1 register">
                    <div class="form-group">
                        <label for="username" class="col-sm-3 control-label">用户名:</label>
                        <div class="col-sm-8">
                            <div class="input-group">
                                <input type="text" class="form-control" name="username" placeholder="请输入用户名">
                                <div class="input-group-addon">
                                    <span class="glyphicon glyphicon-user"></span>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="password" class="col-sm-3 control-label">密码:</label>
                        <div class="col-sm-8">
                            <div class="input-group">
                                <input type="password" class="form-control" name="password" placeholder="请输入密码(六位以上)">
                                <div class="input-group-addon">
                                    <span class="glyphicon glyphicon-lock"></span>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="chkpwd" class="col-sm-3 control-label">确认密码:</label>
                        <div class="col-sm-8">
                            <div class="input-group">
                                <input type="password" class="form-control" name="chkpwd" placeholder="请确认密码">
                                <div class="input-group-addon">
                                    <span class="glyphicon glyphicon-exclamation-sign"></span>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="email" class="col-sm-3 control-label">邮箱:</label>
                        <div class="col-sm-8">
                            <div class="input-group">
                                <input type="text" class="form-control" name="email" placeholder="请输入有效邮箱">
                                <div class="input-group-addon">
                                    <span class="glyphicon glyphicon-envelope"></span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                    <div class="row">
                        <div class="col-md-3 col-md-offset-3 col-xs-12">
                            <button type="reset" class="btn btn-default btn-block">
                                <b>清空</b>
                                <span class="glyphicon glyphicon-remove"></span>
                            </button>
                        </div>
                        <div class="col-md-3 col-xs-12">
                            <button type="submit" class="btn btn-info btn-block">
                                <b>提交</b>
                                <span class="glyphicon glyphicon-arrow-right"></span>
                            </button>
                        </div>
                    </div>
            </form>
        </div>
    </div>
</body>
</html>

运行测试,基本成功。

接着我们来设计一个数据模型类:命名为User.cs。在解决系统方案资源管理器窗口的Models右击,新建项,类,名称User.cs。

下面是该类代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace alexzengnet.Models
{
    public class User
    {
        public int Id { get; set; }
        public string Name{ get; set; }
        public string PassWord { get; set; }
        public string phone { get; set; }
        public string email { get; set; }
    }
}

然后Ctrl+Shift+B,生成解决方案。也就是将这个类进行编译。

打开HomeController.cs,在Index下面加入以下代码

 public ActionResult REG()
        {
            return View();
        }

右击REG,添加视图,这时候需要的强类型视图,所以跟上面添加index视图略有不同。设置如下图:

http://7xvup9.com1.z0.glb.clouddn.com/mvc-5.jpg

然后稍微写一些代码进去,测试一下:

@model alexzengnet.Models.User

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>REG</title>
</head>
<body>
    <div> 
        @using (Html.BeginForm())
        {
            <p>Name:@Html.TextBoxFor(x=>x.Name)</p>
            <p>Password:@Html.PasswordFor(x => x.PassWord)</p>
            <p>Phone:@Html.TextBoxFor(x => x.phone)</p>
            <input type="submit" value="submit" />
        }
    </div>
</body>
</html>

运行了以后,基本能够满足我的要求,现在我对它进行样式化,将我们刚刚做的加载了bootstrap的html页面复制到这边来,注意代码的变化,如下所示:

@model alexzengnet.Models.User

@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <meta charset="utf-8" />
    <link href="~/Content/bootstrap.min.css" rel="stylesheet">
    <script src="~/Scripts/jquery-1.9.0.min.js"></script>
    <script src="~/Scripts/bootstrap.min.js"></script>
    <style>
        body {
            padding-top: 50px;
            color: #FFF;
            background: #444;
        }

        div {
            margin: 5px auto;
        }

        h1 {
            color: #fff;
        }

        #content {
            width: 100%;
            min-height: 600px;
            background: #444;
            padding-top: 20px;
            color: #FFF;
        }

        .register {
            padding: 20px;
            font-weight: 700;
            border: #FFF solid 1px;
            -moz-border-radius: 10px; /* Gecko browsers */
            -webkit-border-radius: 10px; /* Webkit browsers */
            border-radius: 10px; /* W3C syntax */
        }

        .col-sm-3 {
            line-height: 48px;
        }
    </style>
</head>
<body>
    <div id="content">
        <div class="container">
          @using (Html.BeginForm())
          {
                <div class="row">
                    <h1 class="col-md-6 col-md-offset-3 col-xs-10 col-xs-offset-1 page_title ">注册</h1>
                </div>
                <div class="col-md-6 col-md-offset-3 col-xs-10 col-xs-offset-1 register">
                    

                    <div class="form-group">
                        <label for="username" class="col-sm-3 control-label">用户名:</label>
                        <div class="col-sm-8">
                            <div class="input-group">
                                
                                @Html.TextBoxFor(x => x.Name, new { @class= "form-control", @placeholder = "请输入有效用户名" })
                                <div class="input-group-addon">
                                    <span class="glyphicon glyphicon-user"></span>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="password" class="col-sm-3 control-label">密码:</label>
                        <div class="col-sm-8">
                            <div class="input-group">
                                
                                @Html.PasswordFor(x => x.PassWord, new { @class = "form-control", @placeholder = "请输入有效密码"  })
                                <div class="input-group-addon">
                                    <span class="glyphicon glyphicon-lock"></span>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="chkpwd" class="col-sm-3 control-label">电话:</label>
                        <div class="col-sm-8">
                            <div class="input-group">
                                
                                @Html.TextBoxFor(x => x.phone, new { @class = "form-control" , @placeholder= "请输入有效电话" })
                                <div class="input-group-addon">
                                    <span class="glyphicon glyphicon-phone"></span>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="email" class="col-sm-3 control-label">邮箱:</label>
                        <div class="col-sm-8">
                            <div class="input-group">
                              
                                @Html.TextBoxFor(x => x.email, new { @class = "form-control", @placeholder = "请输入有效邮箱" })
                                
                                <div class="input-group-addon">
                                    <span class="glyphicon glyphicon-envelope"></span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-3 col-md-offset-3 col-xs-12">
                        <button type="reset" class="btn btn-default btn-block">
                            <b>清空</b>
                            <span class="glyphicon glyphicon-remove"></span>
                        </button>
                    </div>
                    <div class="col-md-3 col-xs-12">
                        <button type="submit" class="btn btn-info btn-block">
                            <b>注册</b>
                            <span class="glyphicon glyphicon-arrow-right"></span>
                        </button>
                    </div>
                </div>
          }
        </div>
    </div>
</body>
</html>

运行之后,感觉不错,如下图:

这时我们点击注册,将不会有任何反应,下面我们就来研究一下如何写注册的代码。

第一步,先来设置启动URL,点击项目菜单,选择本项目的属性,如本例就是alexzengnet属性。在面板中选择Web,特定页,不用填写任何值即可。如下图。

第二步,我们来修改一下HomeController.cs文件,让它响应http的GET,POST。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using alexzengnet.Models;

namespace alexzengnet.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            int hour = DateTime.Now.Hour;
            ViewBag.SayHi=hour<12?"早上好":"下午好";
            return View();
        }
        [HttpGet]
        public ActionResult REG()
        {
            return View();
        }

        [HttpPost]
        public ActionResult REG(User user)
        {
            return View("Thank", user);
        }
    }
}

这里的意思就是如果MVC获取到user数据,那么将使用post请求。使用post将查找并渲染“Thank”视图。

第三步,创建Thank视图。右击HomeController.cs文件,添加一个强类型菜单视图。如下图:

修改一下新建的Thank.cshtml,代码如下:

@model alexzengnet.Models.User

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Thank</title>
</head>
<body>
    <div>
        <h1>多谢注册本站,@Model.Name</h1> 
    </div>
</body>
</html>

测试一下成功,但对于会员注册,我们往往需要增加一些输入验证,以防止用户一些无效的输入:

第一步打开User.cs,增加验证规则声明,在这个命名空间里面using System.ComponentModel.DataAnnotations; 做验证,下面是代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace alexzengnet.Models
{
    public class User
    {
        public int Id { get; set; }
        [Required(ErrorMessage ="请输入用户名。")]
        public string Name{ get; set; }
        [Required(ErrorMessage = "请输入密码。")]
      
        public string PassWord { get; set; }
        [Required(ErrorMessage = "请输入电话。")]
        
        public string phone { get; set; }
        [Required(ErrorMessage = "请输入Email。")]
        [RegularExpression(".+\\@.+\\..+", ErrorMessage ="请输入正确的Email地址")]
        public string email { get; set; }
    }
}

第二步修改reg.cshtml文件,在需要提示错误的地方加上@Html.ValidationSummary() 以下省略掉不必要的代码,示例如下:

 @using (Html.BeginForm())
          {
                <div class="row">
                    <h1 class="col-md-6 col-md-offset-3 col-xs-10 col-xs-offset-1 page_title ">注册</h1>
                </div>
                <div class="col-md-6 col-md-offset-3 col-xs-10 col-xs-offset-1 register">
                    <div class="alert alert-warning alert-dismissible" role="alert">
                        <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                        <strong>@Html.ValidationSummary()</strong>
                    </div>
                          ......
                          }

第三步修改HomeController.cs文件,做一个判断,如果发生错误提示,就不查找并渲染文件。

[HttpPost]
        public ActionResult REG(User user)
        {
            if (ModelState.IsValid) {
                return View("Thank", user);
            }
            else {
                return View();
            }
            
        }

测试完成!

这一个例子并没有写入数据库,它通过一个全空的MVC,一步一步的往里面填充代码,熟悉一下视图、控制器、MODEL之间的关联,对MVC有了一个初步的了解。

下一个例子我们会用一个简单的留言板作为例子,你将看到用极简单的代码将自动生成留言板,并写入数据库,还有了修改、删除等操作数据库功能。然后我们再对其进行修改,以满足我们的设计需求。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容