当前位置: 首页 > news >正文

实力网站建设/电商数据查询平台

实力网站建设,电商数据查询平台,网站制作百度资源,wordpress登录功能目录 【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5EF6) 【第二篇】ASP.NET MVC快速入门之数据注解(MVC5EF6) 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5EF6) 【第四篇】ASP.NET MVC快速入门之完整示…

目录

【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6)

【第二篇】ASP.NET MVC快速入门之数据注解(MVC5+EF6)

【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)

【第四篇】ASP.NET MVC快速入门之完整示例(MVC5+EF6

【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)

 

请关注三石的博客:http://cnblogs.com/sanshi

 

完善数据注解

到目前为止的表格页面效果:

 

我们需要更多的数据注解,来限制各个属性,以及提供显示用的名称(而不是英文字符串):

public class Student
{public int ID { get; set; }[Display(Name = "姓名")][Required][StringLength(200, MinimumLength = 2)]public string Name { get; set; }[Display(Name = "性别")][Required][Range(0, 1)]public int Gender { get; set; }[Display(Name = "所学专业")][Required][StringLength(200)]public string Major { get; set; }[Display(Name = "入学日期")][DataType(DataType.Date)][DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]public DateTime EntranceDate { get; set; }
}

 

 

再次运行,表格页面效果:

 

完善性别的显示

表格页面-性别列显示为中文

这个比较简单,将原来的:

@Html.DisplayFor(modelItem => item.Gender)

 

 

修改为:

@if (item.Gender == 1)
{@:男
} else
{@:女
}

 

 

新建编辑页面-性别显示为下拉列表

原来的编辑页面:

 

性别字段的编辑框是通过如下方式生成的:

@Html.EditorFor(model => model.EntranceDate, new { htmlAttributes = new { @class = "form-control" } })

 

 

Html辅助方法EditorFor会查看模型属性的类型,自动生成对应的表单输入框。由于性别字段是整形,所以这里默认会生成一个数字输入框。

 

为了更加友好的显示,我们将性别改为下拉列表,并且仅允许用户从下拉项中选择。首先我们需要准备下拉列表选项的集合,并通过控制器传递给视图使用:

 

定义获取性别集合的函数,由于需要多个地方使用,所以提取成一个公共方法:

private List<SelectListItem> GetGenderList()
{return new List<SelectListItem>() {new SelectListItem{Text = "",Value = "1"},new SelectListItem{Text = "",Value = "0"}};
}

 

 

通过ViewBag.GenderList传入视图:

// GET: Students/Edit/5
public ActionResult Edit(int? id)
{if (id == null){return new HttpStatusCodeResult(HttpStatusCode.BadRequest);}Student student = db.Students.Find(id);if (student == null){return HttpNotFound();}ViewBag.GenderList = GetGenderList();return View(student);
}

 

 

视图中通过DropDownListFor强类型辅助方法,来显示下拉列表以及选中项:

@Html.DropDownListFor(model => model.Gender,
ViewBag.GenderList as IEnumerable<SelectListItem>, new { @class = "form-control" })

 

 

 

表单提交时的代码和之前一样,多了一个对GetGenderList的调用:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ID,Name,Gender,Major,EntranceDate")] Student student)
{if (ModelState.IsValid){db.Entry(student).State = EntityState.Modified;db.SaveChanges();return RedirectToAction("Index");}ViewBag.GenderList = GetGenderList();return View(student);
}

 

 

这一点非常重要,虽然正常的提交操作不会再次返回当前视图(RedirectToAction直接指定了页面跳转),但是在模型绑定失败时(尝试禁用JavaScript,姓名留空,然后提交表单),如果不重新设置ViewBag.GenderList参数就会出错:

 

表单检索

下面我们为表格页面增加一个搜索表单,用来对表格数据进行过滤。

 

先增加一些记录:

 

添加表单检索字段:

@using (Html.BeginForm())
{@Html.AntiForgeryToken()<p>所学专业: @Html.DropDownList("Major",
ViewBag.MajorList as IEnumerable<SelectListItem>, "全部")姓名: @Html.TextBox("Name")<input type="submit" value="检索" /></p>
}

 

 

由于本示例比较简单,没有单独的表来存储所学专业,因此我们需要从用户表中检索,并存储到ViewBag.MajorList中传入视图:

private List<SelectListItem> GetMajorList()
{var majors = db.Students.OrderBy(m => m.Major).Select(m => m.Major).Distinct();var items = new List<SelectListItem>();foreach(string major in majors){items.Add(new SelectListItem {Text = major,Value = major});}return items;
}// GET: Students
public ActionResult Index()
{ViewBag.MajorList = GetMajorList();return View(db.Students.ToList());
}

 

 

页面运行效果:

 

增加POST请求的处理方法:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string Major, string Name)
{var students = db.Students as IQueryable<Student>;if (!String.IsNullOrEmpty(Name)){students = students.Where(m => m.Name.Contains(Name));}if (!String.IsNullOrEmpty(Major)){students = students.Where(m => m.Major == Major);}ViewBag.MajorList = GetMajorList();return View(students.ToList());
}

 

 

此时的运行效果:

 

数据库分页

分页工具条

首先改造视图代码,增加分页工具条:

<div id="pagebar">@for (var i = 0; i < ViewBag.PageCount; i++){if (i == ViewBag.PageIndex){<span class="currentpagenumber">@(i + 1)</span>}else{<a class="pagenumber" href="javascript:;">@(i + 1)</a>}}
</div>

 

 

其中ViewBag.PageIndexViewBag.PageCount是由控制器传入的分页参数,我们需要这两个数据来构造分页链接,如果是当前分页就显示为文本,如果是其他页就显示为超链接,然后通过客户端JavaScript来注册点击事件。

 

EF的数据库分页

后台控制器代码:

private static readonly int PAGE_SIZE = 3;private int GetPageCount(int recordCount)
{int pageCount = recordCount / PAGE_SIZE;if (recordCount % PAGE_SIZE != 0){pageCount += 1;}return pageCount;
}private List<Student> GetPagedDataSource(IQueryable<Student> students,
int pageIndex, int recordCount)
{var pageCount = GetPageCount(recordCount);if (pageIndex >= pageCount && pageCount >= 1){pageIndex = pageCount - 1;}return students.OrderBy(m => m.Name).Skip(pageIndex * PAGE_SIZE).Take(PAGE_SIZE).ToList();
}// GET: Students
public ActionResult Index()
{var students = db.Students as IQueryable<Student>;var recordCount = students.Count();var pageCount = GetPageCount(recordCount);ViewBag.PageIndex = 0;ViewBag.PageCount = pageCount;ViewBag.MajorList = GetMajorList();return View(GetPagedDataSource(students, 0, recordCount));
}

 

 

EF为我们封装了大部分的细节,所以上面的数据库分页代码非常直观和容易理解:

students

       .OrderBy(m => m.Name)

       .Skip(pageIndex * PAGE_SIZE)

       .Take(PAGE_SIZE).ToList()

 

完成一个典型的数据库分页需要如下几部:

1.     OrderBy:指定排序列

2.     Skip:跳过多少条记录

3.     Take:返回的最大记录数

 

上面的OrderBy是必须指定的,否则就会报错:

 

分页SQL语句

完成上面的代码,分页效果已经出来了:

 

下面,我们使用第三方Express Profiler工具来检查EF生成的数据库分页SQL语句。

 

首先下载工具:

http://expressprofiler.codeplex.com/

 

打开Express Profiler,在Server文本框中输入(LocalDb)\MSSQLLocalDB,如果你使用的VS2013,这个字符串可能是:(LocalDb)\v11.0,点击绿色的启用按钮:

 

运行我们的示例,转到学生列表页面,然后清空Express Profiler中的全部显示,再点击第二页:

 

可以看到这里有3SQL查询,这个和我们的心理预期是一样的:

1.     第一次SQL查询:总记录数

SELECT

    [GroupBy1].[A1] AS [C1]

    FROM ( SELECT

        COUNT(1) AS [A1]

        FROM [dbo].[Students] AS [Extent1]

    )  AS [GroupBy1]

go

 

对应的C#代码:

var students = db.Students as IQueryable<Student>;

var recordCount = students.Count();

 

2.     第二次SQL查询:所学专业集合(去除重复)

SELECT

    [Distinct1].[Major] AS [Major]

    FROM ( SELECT DISTINCT

        [Extent1].[Major] AS [Major]

        FROM [dbo].[Students] AS [Extent1]

    )  AS [Distinct1]

go

 

对应的C#代码:

var majors = db.Students.OrderBy(m => m.Major).Select(m => m.Major).Distinct();

 

3.     第三次SQL查询:分页数据

SELECT

    [Extent1].[ID] AS [ID],

    [Extent1].[Name] AS [Name],

    [Extent1].[Gender] AS [Gender],

    [Extent1].[Major] AS [Major],

    [Extent1].[EntranceDate] AS [EntranceDate],

    [Extent1].[Job] AS [Job]

    FROM [dbo].[Students] AS [Extent1]

    ORDER BY [Extent1].[Name] ASC

    OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY

go

 

对应的C#代码:

return students.OrderBy(m => m.Name)

.Skip(pageIndex * PAGE_SIZE)

.Take(PAGE_SIZE).ToList();

 

这个查询顺序也和前面的EF代码的执行顺序一模一样,可以再回过头看下控制器Index方法。

 

同时处理表单检索和数据库分页

不过目前遇到点难题,我们希望实现如下两个功能:

1.     点击分页链接时会发出HTTP POST请求,在请求参数中带上表单检索值。

2.     表单检索时,在请求参数中带上当前所在的分页索引。

 

实现这两个功能才算完善,否则表单检索时如果丢失分页参数,就会回到第一页;而分页时如果丢失表单参数,就会清空表单输入框。

 

是不是开始怀念WebForms了,在WebForms中整个页面都被包含在一个表单中,因此回发时根本不需要考虑哪些参数后台需要。而MVC中这个就需要我们操心了,毕竟在灵活性的面前,便利性就会有所打折。

 

我们采取的办法是扩充前面的form标签,加入PageIndex隐藏字段,然后点击分页链接时提交表单即可:

@using (Html.BeginForm("Index", "Students", FormMethod.Post, new { id = "searchForm" }))
{@Html.AntiForgeryToken()<p>所学专业: @Html.DropDownList("Major",
ViewBag.MajorList as IEnumerable<SelectListItem>, "全部")姓名: @Html.TextBox("Name")<input type="hidden" id="PageIndex" name="PageIndex" value="0" /><input type="button" id="searchButton" value="检索" /></p>
}

 

 

注册JavaScript脚本来处理点击[检索]按钮和分页链接:

@section scripts {<script>function submitForm(pagenumber) {pagenumber = parseInt(pagenumber, 10);$('#PageIndex').val(pagenumber - 1);$('#searchForm').submit();}$(function () {$('#searchButton').click(function () {submitForm($('#pagebar .currentpagenumber').text());});$('#pagebar .pagenumber').click(function () {submitForm($(this).text());});});</script>
}

 

 

现在看下效果,首先检索所学专业:

 

然后点击第二页,会发出一个POST请求:

 

可以看到本次请求,上面的用户输入和PageIndex都发送到了控制器处理方法:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string Major, string Name, int PageIndex)
{var students = db.Students as IQueryable<Student>;if (!String.IsNullOrEmpty(Name)){students = students.Where(m => m.Name.Contains(Name));}if (!String.IsNullOrEmpty(Major)){students = students.Where(m => m.Major == Major);}var recordCount = students.Count();var pageCount = GetPageCount(recordCount);if (PageIndex >= pageCount && pageCount >= 1){PageIndex = pageCount - 1;}students = students.OrderBy(m=>m.Name).Skip(PageIndex * PAGE_SIZE).Take(PAGE_SIZE);ViewBag.PageIndex = PageIndex;ViewBag.PageCount = pageCount;ViewBag.MajorList = GetMajorList();return View(students.ToList());
}

 

 

这里需要注意一点:先进行表单过滤,然后执行获取总记录数的查询,最后再获取分页数据。这个顺序不能变,因为表单过滤后总记录才能确定下来。

 

小结

本篇文章对示例进行了完善,首先是添加更多的数据注解,然后将显示的性别由数字改为字符串,对于编辑和新建页面,将性别渲染为下拉列表。然后为表格页面增加表单检索功能,可以根据[所学专业][姓名]对表格过滤,最后完成了数据库分页功能。

本系列文章至此已经完成了,下面我们简单总结下用到的关键词:路由引擎、控制器向视图传值、强类型辅助方法、模型绑定、数据注解、数据迁移、客户端验证、服务器端模型验证、模拟POST请求、表单身份验证、跨站请求伪造、过多提交攻击、表单检索、数据库分页。

下载示例源代码

 

能回复评论的别推荐了,免得又被说推荐数异常。发个博客园文章一定要心平气和,套用一句流行语:

小编虐我千百遍,我待小编如初恋。

 

http://www.jmfq.cn/news/4770433.html

相关文章:

  • 江苏省建设局官方网站查询/网站推广的全过程
  • 网站友链是什么情况/建设网站费用
  • 网站推广的方法包括/站长之家seo工具包
  • linux宝塔面板做网站/app拉新怎么做
  • 帮客户做网站挣钱吗/网络营销的策略有哪些
  • 电子商务是学什么的/seo优化培训机构
  • 网站设计与网站开发是同时进行的/初学者做电商怎么入手
  • 企业网站在哪里建/今日nba数据帝
  • 京东商城网站建设/网络营销seo是什么意思
  • 做内容网站好累/seo提升关键词排名
  • 学做招投标的网站有哪些/兰州网络推广与营销
  • wordpress 权重/成都网站排名 生客seo
  • 易尔通做网站怎么样/经典软文
  • 代做电子商务网站作业/aso推广优化
  • 后缀cc的网站/南宁推广软件
  • 公司网站制作流程2016/seo流量排名工具
  • 公司彩页宣传手册/sem优化服务公司
  • 网站建设it/seo培训学什么
  • win7做本地网站/抖音关键词搜索排名
  • 510企业网站系统源码/软文街官方网站
  • 深圳seo网站推广报价/seo广州工作好吗
  • 惠阳网站建设/新闻头条最新消息摘抄
  • 网站建设外包 排名/泉州关键词排名
  • 买医疗产品的网站建设/互联网媒体推广
  • 武陟做网站/国内最新的新闻
  • 网站开发学那个语言比较好/企业建站公司
  • wordpress后台分类添加图片/seo优化公司排名
  • 雅诗兰黛网络营销策划方案/最新seo视频教程
  • 桐乡哪里有做网站的/青岛做网站推广
  • 石家庄网站建设多少钱/百度快速排名用是