ASP.NET MVC 开发实例:简单留言板的开发

ASP.NET MVC 开发实例:简单留言板的开发

上一个例子 我们使用手动创建一个注册会员的实例,熟悉了一下视图、控制器、MODEL之间的关联,对MVC有了一个初步的了解。

本例子是一个ASP.NET MVC开发简单留言板的例程,使用了MVC已经配置好的组件进行开发,也许你会惊讶于开发的速度,在还没怎么动手,程序已经可以写入数据库了,增删改一个不少的呢!本例程参考《ASP.NET MVC 4开发指南》第三章:新手上路初体验。有需要的朋友请购买本书。

现在,我们从新建项目开始。

新建一个项目,名字取为GuestBook,点击确定。

在弹出来的新建项目窗口上,选择为MVC模板。

构建文件需要一点时间,完成了以后按F5已经可以运行网站了。可以看见,ASP.NET MVC为我们打造了一个美观大方的首页。

下面我们来创建数据模型:

第一步:在“解决方案资源管理器”窗口选择Models目录,右击,在弹出的菜单选择添加-类,取名为Guestbook.cs,点击添加。

第二步:修改Guestbook.cs代码,定义出一个基本留言板所需要的数据类型.

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

namespace GuestBook.Models
{
    public class Guestbook
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Content { get; set; }
    }
}

第三步:点击Ctrl+Shift+B,生成解决方案。也就是将这个类进行编译。

做过上一个实例的朋友一定会明白,为什么需要进行编译。接下来,我们将创建控制器、动作和视图。

第一步:在“解决方案资源管理器”窗口选择Controllers目录,右击,在弹出的菜单选择控制器。

第二步:选择包含视图的MVC5控制器(使用Entity Framework)

第三步:弹出添加控制器的对话框,模型类选择Guestbook(GuestBook.Models),数据上下文点击右端的加号,会自动弹出一个对话框,默认“GuestBook.Models.GuestBookContext”点击添加,控制器默认为GuestbooksController,点击添加。

好了,完成了留言板了。

点击F5,http://localhost:/Guestbooks/Index 浏览一下,是不是已经有了,还有Create New等页面十分标致。

的确,这样的页面很省事,但满足不了我们的要求,一般来说,一个自动生成的程序,我们需要对它页面UI、程序功能进行修改。页面修改其实不难,一些功能上的修改就显得有点困难了。

例如,像上一节的例子一样,我们需要增加一些输入验证,以防止用户一些无效的输入。你也许会说,这个不难,前面我学习了。于是打开Guestbook.cs进行修改。

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

namespace GuestBook.Models
{
    public class Guestbook
    {
        public int Id { get; set; }
        [Required(ErrorMessage = "请输入用户名。")]
        public string Name { get; set; }
        [Required(ErrorMessage = "请输入Email。")]
        public string Email { get; set; }
        [Required(ErrorMessage = "请输入内容。")]
        public string Content { get; set; }
    }
}

然后运行一看,傻眼了,出错了。

这是因为在使用EF Code First时,当Model发生变更时,默认会引起System.InvalidOperationException异常。

那么要怎么办呢?

解决问题的最简单的方法就是砍掉整个数据库重建。关于如何迁移数据,点击 http://msdn.microsoft.com/en-us/data/jj591621.aspx 有详细说明。现在我们在新建整段代码,数据丢失并没有多大问题。

打开Global.asax.cs,在protected void Application_Start() 下面输入代码:

 protected void Application_Start()
        {
            System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<GuestBook.Models.GuestBookContext>());

            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }

运行一下,错误解除。当然数据也就消失了。

现在可以随意的修改Guestbook.cs文件了,例如做如下修改:

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

namespace GuestBook.Models
{
    public class Guestbook
    {
        public int Id { get; set; }
        [Required]
        [DisplayName("姓名")]
        public string Name { get; set; }
        [Required]
        [DisplayName("电子邮件")]
        public string Email { get; set; }
        [Required]
        [DisplayName("内容")]
        public string Content { get; set; }
    }
}

这样我们就可以放心调试,数据丢失了也没什么大问题。一直修改到我们满意为止。

但是如果将来产品上线了,要记得去掉刚刚写在Global.asax.cs文件上的代码。否则修改模型的话,数据又将丢失。

下面进行代码重构,留言板只需要显示留言和增加留言。对页面进行重构的同时增强对MVC的认识。

首先,打开Controller文件夹,对GuestbooksController.cs文件进行修改。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using GuestBook.Models;

namespace GuestBook.Controllers
{
    public class GuestbooksController : Controller
    {
        private GuestBookContext db = new GuestBookContext();
        // 显示留言
        // GET: Guestbooks
        public ActionResult Index()
        {
            return View(db.Guestbooks.ToList());
        }

        // GET: Guestbooks/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Guestbook guestbook = db.Guestbooks.Find(id);
            if (guestbook == null)
            {
                return HttpNotFound();
            }
            return View(guestbook);
        }

        // GET: Guestbooks/Create
        public ActionResult Write()
        {
            return View();
        }

        // POST: Guestbooks/Create
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Write([Bind(Include = "Id,Name,Email,Content")] Guestbook guestbook)
        {
            if (ModelState.IsValid)
            {
                db.Guestbooks.Add(guestbook);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(guestbook);
        }

        
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

可以看出,我们已经将编辑、删除的有关代码给去掉(因为留言板不需要这些功能,如果需要也是在管理员的权限下面,此处不做这方面的讨论),将Create改成Write,同样的,我们也需要将Create.cshtml改名为Write.cshtml,下面我们看看它的源代码:

@model GuestBook.Models.Guestbook

@{
    ViewBag.Title = "Write";
}

<h2>留下足迹</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Guestbook</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Content, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Content, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Content, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="发表留言" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("回到留言列表", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

运行测试成功,页面自动返回到index处,这个页面也需要进行修改,打开index.cshtml文件:

@model IEnumerable<GuestBook.Models.Guestbook>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("写下留言", "Write")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Email)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Content)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Email)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Content)
        </td>
        <td>
           
            @Html.ActionLink("显示留言", "Details", new { id=item.Id }) 
           
        </td>
    </tr>
}

</table>

显示留言页面也稍微做个更改:

@model GuestBook.Models.Guestbook

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
    <h4>Guestbook</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Name)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Name)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Email)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Email)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Content)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Content)
        </dd>

    </dl>
</div>
<p>
   
    @Html.ActionLink("回到留言列表", "Index")
</p>

好了,运行程序,这个留言板已经基本可以满足我们的要求了。它并不完美,但它对初学者来说,是一次非常不错的开发入门之旅。

从下一章开始,我们将入门再入得深一点点,开发一个简单商城网站实例,谢谢您的支持。转帖的时候请把凉风有兴或者AlexZeng.net进行署名。本文版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证

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

推荐阅读更多精彩内容