RT,小弟不才,之前做webform,三层架构3年。因为公司要做自己的商城网站,三层确实是做腻了,想用点不一样的技术。于是瞄上了MVC,一了解最新的是MVC5,就直接从MVC5开始吧。
如果您和我一样,之前没接触过MVC,想学习MVC的话。推荐一篇MVC5学习教程:http://www.cnblogs.com/youring2/p/3192682.html (据说是MVC5官方文档的译文。) 文章目录如下:
- 添加控制器
- 添加视图
- 修改视图和布局页
- 控制器传递数据给视图
- 添加模型
- 创建连接字符串
- 通过控制器访问模型的数据
- 生成的代码详解
- 使用 SQL Server LocalDB
- Edit方法和Edit视图详解
- 添加查询
- Entity Framework 数据迁移之添加字段
- 添加验证
- Details 和 Delete 方法详解
废话够了,那么现在就记录下我在学习使用MVC5做网站过程当中遇到的问题。
从控制器开始。
1、 传参数上文会给出详细的方法。想提醒的是:MVC中同样可以用/Controller/Action?id=123 和MVC的/Controller/Action/123都可以使用
这样在控制中,
public ActionResultAction()
{
string idm= Request.QueryString["id"].ToString();//
return View();
}
Request.QueryString同样可以接受参数哦
既然说道获取了,那么再多嘴一句。
控制器中 string UserName = Request.Form["UserName"].Trim(); 可以获取到view表单中<input type="text" name=”UserName“>
2、 关于Session
//网站中常用的检查session 如果没有 alert提示跳转到登录页面,在控制器中主方法的返回类型是ActionResult,那么要怎么做呢
public ActionResult Action()
{
if(Session["_userid"]==null){
return Content("<script>alert('您不是管理员或登录超时!');window.location='/User/Login'</script>");
}
else
{
return View();
}
}
3、linq增删改查
//增加
CrossWayDBEntities db = new CrossWayDBEntities();//数据库上下文
Address addressM = new Address();
string addStr=Guid.NewGuid().ToString();
addressM.AddressID =addStr;
addressM.AddDateTime = DateTime.Now;
addressM.UserID = _userid;
addressM.ReceiptName = ReceiptName;
addressM.ReceiptProvince = Province;
addressM.ReceiptCity = City;
addressM.ReceiptDistrict = District;
addressM.Stairs = Stairs;
addressM.ReceiptTime = ReceiptTime;
addressM.ZipCode = ZipCode;
addressM.PhoneNO=PhoneNO;
addressM.Email=Email;
try {
db.tb_Address.Add(addressM);
db.SaveChanges();
} catch (DbEntityValidationException ex) {
var entityError = ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.ErrorMessage);
var getFullMessage = string.Join("; ", entityError);
var exceptionMessage = string.Concat(ex.Message, "errors are: ", getFullMessage); }
需要注意的是:catch中的代码 因为在添加数据等操作时可能会有莫名其妙的错误,这些错误很有可能是因为你字段类型和长度和数据库不匹配 在上述catch中的var getFullMessage,var exceptionMessage 可以看到详细的错误提示。
//删除
public ActionResult Delete(string id, string returnurl)
{
tb_OrderDetails orderDelete = db.tb_OrderDetails.SingleOrDefault(tb_OrderDetails => tb_OrderDetails.OrderID == id);
db.tb_OrderDetails.Remove(orderDelete);
db.SaveChanges();
return Content("<script>alert('删除成功!');window.location='" + returnurl + "'</script>");
}
//修改
tb_OrderDetails orderUpdate = db.tb_OrderDetails.SingleOrDefault(tb_OrderDetails => tb_OrderDetails.OrderID == id);
goodsId= orderUpdate.GoodsID;
goodsCount=Convert.ToInt32(orderUpdate.GoodsCount);
orderUpdate.ChangeFlag = false;
db.SaveChanges();
//查询和分页 单表查询就不说了,在做网站中我要用到两表联结查询,在MVC中却如此蛋疼,说多了都是泪啊,卡了我一两天时间。 MvcPager分页的介绍:http://www.webdiyer.com/mvcpager/demo/basic/
public ActionResult Index(int id = 1)
{
if (Session["_userid"] == null)
{
return Content("<script>alert('请登录后重试!');window.location='/User/Login?returnURL=" + Request.RawUrl + "'</script>");
}
//var cartList=from s in db.tb_Cart where s.UserID==Session["_userid"].ToString() select s;
//var cartList2=db.Goods.OrderByDescending(p => p.AddDate).ToPagedList(id, 8);
// var cartList = (db.tb_Cart.OrderByDescending(tb_Cart => tb_Cart.UserID == Session["_userid"].ToString())).ToPagedList(id, 8);
string uid=Session["_userid"].ToString();
var cartList = (from p1 in db.tb_Cart
from p2 in db.Goods
where p1.GoodsID == p2.GoodsID && p1.UserID == uid
orderby p1.AddDateTime descending
select new CartAndGoods
{
GoodsName = p2.GoodsName,
GoodsID=p2.GoodsID,
GoodsIMG = p2.GoodsIMG,
GoodsPrice = p2.MemberPrice,
GoodsNumber = p1.GoodsNumber,
CartID=p1.CartID,
TPrice = p2.MemberPrice * p1.GoodsNumber
}).ToPagedList(id,8);
ViewBag.cartList = cartList;
return View(cartList);
}
linq的两表联结查询,当然肯定有别的写法,我就不纠结了,就按这个说吧。看到select new CartAndGoods 没。因为是两表数据,所以我新建了一个实体类 CartAndGoods来装Cart和Goods表中需要显示的数据。为什么要这么干,就是因为select new 这个new导致的查询的数据是匿名的。问题详细:http://q.cnblogs.com/q/61779/ 我使用的是新建一个model的方法。这样做有一个好处,就是针对 MvcPager分页控件的使用。我们来看一段这个分页控件在View中的代码
头部:
@model PagedList<CrossWayWeb.Models.CartAndGoods>
@using Webdiyer.WebControls.Mvc;
@{ Layout = "~/Views/Shared/_Layout.cshtml"; ViewBag.title = "Cart";}
//分页代码
<div class="fan">
@Html.Pager( Model, new PagerOptions { PageIndexParameterName = "id", PagerItemsSeperator = "", CurrentPagerItemWrapperFormatString = "<span class=\"current\">{0}</span>" }, new { id = "flickrpager" })@section Scripts{@{Html.RegisterMvcPagerScriptResource();}}
</div>
请看红字部分。这个控件需要放进去的是Model,模型 。而我在后台也是自建的一个模型CartAndGoods ,这样就万事大吉了。
来看下View中的代码 如果控制器中是 通过return View(.....)返回数据的
public ActionResult Index(int id = 1) {
if (Session["_AdminFlag"] != null)//有管理员权限
{
return View(db.Goods.OrderByDescending(p => p.AddDate).ToPagedList(id, 8));
}
else
{
return Content("<script>alert('您不是管理员或登录超时!');window.location='/User/Login'</script>");
}
}
那么在View中 直接遍历Model就行了
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.GoodsName)
</td> ........
那如果数据在控制器中是放在ViewBag中的
var _goodsbyid = db.Goods.Where(a => a.GoodsID.ToString() == h_goodsID).ToList();
ViewBag.goodlist = _goodsbyid;
return View();
View中是这样遍历的
@foreach (var CE in ViewBag.goodlist)
{
<div class="colohu">
<dl>
<dt><img src="@CE.GoodsIMG" width="90" height="90" /></dt>
<dd style="font-size:16px; color:#2b2b2b; font-weight:bold;">@CE.GoodsName</dd>
<dd>@CE.ColorOREdition</dd>
</dl>
</div>
<div class="shuli"><span>@CE.GoodsCount</span>
<span style="margin-left:140px;">¥@CE.MemberPrice 元</span>
</div>
}
mvc razor语法很强大
<div class="gina">
<ul>
@if (Session["_userid"] != null && Session["_username"] != null)
{
<li>欢迎您! @Session["_username"].ToString()</li>
<li>@Html.ActionLink("安全退出", "LoginOff","User")</li>
} else
{
<li>@Html.ActionLink("登录", "Login", "User")
</li>
<li>@Html.ActionLink("注册", "Register", "User")
</li>
}
@if (Session["_AdminFlag"] != null)
{
<li>@Html.ActionLink("商品管理", "Index", "Goods")</li>
}
//控制器传页面
return RedirectToAction("Index", "Order");
return Redirect(url);
return Content("<script>alert('您不是管理员或登录超时!');window.location='/User/Login'</script>");
//View传页面
@Html.ActionLink("Edit", "Edit", new { id=item.GoodsID })
@Html.ActionLink("删除", "del", new { id = item.GoodsID }, new { onclick = "return confirm('确认删除?')" })
数据遍历中点击图片的链接
@foreach (var item in ViewBag.Olist)
{
<div class="unpay">
<table width="910" border="0">
<tr>
<td width="70" height="60"><a href="/Products/Purchase/@item.GoodsID"><img src="...".......