载自 asp.net MVC2开发实战
一.Asp.net web from 和mvc在查找文件位置时的区别
MVC的网址路径与文件路径的对应关系是通过网址路由来定义的。可以从Global.asax.cs文件RegisterRoutes()方法。{controller}/{action}/{id}
当输入 http://localhost/Home/About时,通过Routing对应,会对应出 {controller}为home,action为about。所以MVC会先进入Controllers目录找到Home控制器即(HomeController.cs文件.),然后找到about方法,这个方法就是mvc的action,也是实际执行网页主要程序的入口
二.创建View write
<h2>Writeh2>
<%
using (Html.BeginForm("Save","Guestbook",FormMethod.Post))
{
%>
Account:<%=Html.TextBox("username")
%>
<br/>
password:<%=Html.Password("password")
%>
<br />
<inputtype="submit"value="submit"
/>
<%} %>
这句using (Html.BeginForm("Save","Guestbook",FormMethod.Post))表示窗口会将数据发送给Guetbook控制器的Save动作
因为送出窗口的对象与当前View所在的controller相同,只是Action不同,所以可以运用以下技巧,通过View的RouteData.Values对象取得当前的俄所有路由值,并动态加载路由值中的Controller的名称。
using (Html.BeginForm("Save",RouteData.Values["controller"].ToString()))
整个 Write和Save的代码如下
View/write见上面的代码
View/Save:
<h2>Saveh2>
<h2>show Messageh2>
<% = Html.Encode(ViewData["Content"])%>
<% = Html.Encode(ViewData["password"])%>
Controllers/GuestbookController.cs
[AcceptVerbs(HttpVerbs.Post)]
public ActionResultSave()
{
string struser = Request.Form["username"];
string strpass = Request.Form["password"];
ViewData["Content"] = "Uid:" + struser +"Pwd:" + strpass;
ViewData["password"] =strpass;
return View();
}
三.实体类 Entity
在models层新建MVCGuestbook.edmx新增一个实体product
将save更改以下将数据保存在数据库中并通过index展示
public ActionResultIndex()
{
Models.MvcGuestbookentities db =new Models.MvcGuestbookentities();
var data = db.Products;
return View(data);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResultSave(string username,stringpassword)
{
Models.MvcGuestbookentities db =new Models.MvcGuestbookentities();
db.AddToProducts(new Models.Product() { ProductID =Convert.ToInt32(username),ProductName = password });
db.SaveChanges();
ViewData["Content"] = "Uid:" + username +"Pwd:" + password;
ViewData["password"] =password;
return View();
}
在index方法中右击Add View选择新增强类型视图 ,选择 MvcApplication.Models.Product。并在ViewContent中选择list
MVC会自动帮助创建一个View
<h2>Indexh2>
<table>
<tr>
<th>th>
<th>
ProductID
th>
<th>
ProductName
th>
<th>
SupplierID
th>
<th>
CategoryID
th>
<th>
QuantityPerUnit
th>
<th>
UnitPrice
th>
<th>
UnitsInStock
th>
<th>
UnitsOnOrder
th>
<th>
ReorderLevel
th>
<th>
Discontinued
th>
tr>
<% foreach (var itemin Model) { %>
<tr>
<td>
<%: Html.ActionLink("Edit","Edit",new{ id=item.ProductID }) %>|
<%: Html.ActionLink("Details","Details",new { id=item.ProductID })%> |
<%: Html.ActionLink("Delete","Delete",new{ id=item.ProductID })%>
td>
<td>
<%: item.ProductID%>
td>
<td>
<%: item.ProductName%>
td>
<td>
<%: item.SupplierID%>
td>
<td>
<%: item.CategoryID%>
td>
<td>
<%: item.QuantityPerUnit%>
td>
<td>
<%:String.Format("{0:F}", item.UnitPrice)%>
td>
<td>
<%: item.UnitsInStock%>
td>
<td>
<%: item.UnitsOnOrder%>
td>
<td>
<%: item.ReorderLevel%>
td>
<td>
<%: item.Discontinued%>
td>
tr>
<% } %>
table>
<p>
<%: Html.ActionLink("CreateNew","Create") %>
p>
四.修改MVC
使用视图数据模型
因为MCVC会通过Model Binder机制自动将输入的参数邦定到指定的Model上,当使用Action接收一个Model对象时,通常都回自动邦定所有输入的数据。
ViewModel的创建过程。在Models目录下新建一个数据类型,命名为GuestForm
设置几个字段
public class GuestbookForm
{
public string name {get; set; }
public string email {get;set; }
public string content{get; set; }
}
修改Views/Guestbook/Write.aspx页面的Inherits属性修改为强类型:继承自GuestbookForm
Inherits="System.Web.Mvc.ViewPage
修改原程序中的 Account:<%=Html.TextBox ("username")
将所有的字段都变为强类型的语法
<%
using (Html.BeginForm("Save","Guestbook",FormMethod.Post))
{
%>
<%=Html.LabelFor(x=>x.name)%>
<%=Html.TextBoxFor (x=>x.name)
%>
<br/>
<%=Html.LabelFor(x=>x.content)%>:
<%=Html.TextBoxFor(x=>x.content)
%>
<br />
<inputtype="submit"value="submit"
/>
<%} %>
接下来修改Save动作改为 public ActionResultSave(Models.GuestbookForm data)
使用这个机制,将自动通过QueryString()方法或Form()方法传来的参数找到对应的强类型对象中的属性
public ActionResultSave(Models.GuestbookForm data)
{
Models.MvcGuestbookentities db =new Models.MvcGuestbookentities();
db.AddToProducts(new Models.Product() { ProductID =Convert.ToInt32(data.name),ProductName = data.content });
db.SaveChanges();
ViewData["Content"] = "Uid:" + data.name +"Pwd:" + data.content;
ViewData["password"] =data.content;
return View();
}
避免用户重复发送消息
使用PRG的方式避免。
PRG介绍
将用户点击提交按钮从而发出POST请求,页面提交跳转和显示结果页面这三个行为分离开. PRG正是遵循这种思路, Client用POST方法请求Server响应数据变更, Server用Redirect方法将response指定到另一个URL上的结果页面, Client所有对页面显示的请求都用GET方法告知Server.这样, "后退再前进"或刷新页面的行为都发出的是GET请求,从而不会对server产生任何数据更改的影响, double submit problem得以解决.
修改:删除/View/Guestbook/Save.aspx页面
修改GuestbookController.cs页面。更改save方法,新增Result方法
[AcceptVerbs(HttpVerbs.Post)]
public ActionResultSave(Models.GuestbookForm data)
{
TempData["LastPostGuestbookFormData"]= data;
return RedirectToAction("Result");
}
public ActionResultResult()
{
if (TempData["LastPostGuestbookFormData"]==null)
{
return RedirectToAction("Index");
}
var model = (Models.GuestbookForm)TempData["LastPostGuestbookFormData"];
return View(model);
}
新建result动作的视图,选择Details选项显示单笔数据
<asp:ContentID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Resulth2>
<fieldset>
<legend>Fieldslegend>
<divclass="display-label">namediv>
<divclass="display-field"><%: Model.name%>div>
<divclass="display-label">emaildiv>
<divclass="display-field"><%: Model.email%>div>
<divclass="display-label">contentdiv>
<divclass="display-field"><%: Model.content%>div>
fieldset>
<p>
<%: Html.ActionLink("Edit","Edit",new{ /* id=Model.PrimaryKey */ })%> |
<%: Html.ActionLink("Backto List","Index") %>
p>
MVC执行的生命周期
如果一个网站的网址为http://localhost?Member?Login.aspx如果在网站的根目录中有使用ASP.NET Web Forms编写的“/Member/Login.aspx”存在, MVC就不会应用UrlRouting,而是将流程的控制权交给IIS,并有IIS将其交由下一个模块执行。如果“/Member/Login.aspx”不存在,那么MVC的Routing就会正式启动对比。
如果在Golbal.asax文件的Application_Start()事件的最前面将RouteTable.Routes.RouteExistingFiles参数设置为Ture,MVC的UrlRouting就不会先判断是否有实体文件存在。它会先用Re个isterRoutes方法中定义的网址路有规则一一对比,如果成功就会用Asp.Net MVC进行处理,失败则将执行的权力交换给IIS。
实体类linqtosql
namespace MvcGuestBookEntity.Models
{
public class MemberRepostority : IMenberIRepostority
{
DataClasses1DataContext db = new DataClasses1DataContext();
IQueryable IMenberIRepostority.FindAllMenber()
{
return db.Employees;
}
Employee IMenberIRepostority.GetMemberById(int EmployeeID)
{
return db.Employees.Where(p => p.EmployeeID == EmployeeID).FirstOrDefault();
}
void IMenberIRepostority.Add(Employee e)
{
db.Employees.InsertOnSubmit(e);
}
void IMenberIRepostority.save()
{ db.SubmitChanges(); }
}
}
namespace MvcGuestBookEntity.Interface
{
interface IMenberIRepostority
{
IQueryable FindAllMenber();
Employee GetMemberById(int id);
void Add(Employee member);
bool delete(int id);
void save();
}