MVC笔记
来源:互联网 发布:国信炒股软件 编辑:程序博客网 时间:2024/06/05 11:49
MVC基础介绍
MVC是一种架构模式(Architectural pattern),用以描述应用程序的结构以及结构中各部分的职责和交互方式.
MVC模式的目的是实现一种动态的程式设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外此模式通过对复杂度的简化使程序结构更加直观
二、MVC各层次职责分解:
模型-视图-控制器架构模式背后的思想非常简单:我们的应用程序中必须区分下面这些职责:
模型(Model):
模型是指运用于数据之上的数据规则和数据内容,它一般对应于应用程序所要管理的对象。在软件系统中,任何事物都可以被抽象成可以对其以某种方式进行处理的数据模型。应用程序中的用户,信息以及图书是什么?它们只是一堆必须按照对应规则处理的数据(日期不能是未来的日期,电子邮件有特定的格式,名字的长度不能超过多少字符等等)模型给控制器提供了一个用户请求内容对应的数据表达(比如信息,书,相册)。不管我们如何向用户展示,这个数据模型都不会变。这也是我们为什么可以随意选择使用哪个视图来展示数据的原因。模型包含我们应用程序逻辑中最重要的组成部分,这些逻辑运用于我们要处理的问题过程中。控制器更多的是包含应用程序自身的内部组织逻辑(更像管家)。
视图(View):
视图提供了展示模型数据的不同方式。它可能是数据填充的模板。视图可以有多个,而控制器则决定使用哪个视图。一个网络应用通常由许多控制器,模型和视图组成。控制器可以被看成是一个主控制器,用于接收用户的所有请求,然后在调用特定的控制器来处理不同的情况。
控制器(Controller):
控制器掌管着用户的请求(当用户点击图形用户界面(GUI)上的元素执行操作时,控制器会收到HTTP GET或者POST请求)。它的主要功能就是调用并协调需要的资源/对象来执行用户请求。通常控制器会为任务调用合适的模型,以及选择合适的视图。
各层间调用关系:
我们先来看一下当用户访问mvc框架站点时的序列图
现在我们假设正在开发一个人事系统的员工展示业务,首先Controller收集用户提交过来的条件信息,根据条件信息调用Model,在Model中会把条件传给业务逻辑层,业务逻辑层会根据条件从数据库中获得相应的数据,然后将数据返回给Model,在Model中会将数据进行封装后传给Controller,然后Controller再根据需要显示的格式将相应的数据传给View,在View中执行显示逻辑,最后Controller将所要的View传给用户。
Controller可以直接控制View和Model,View中可以直接控制Model,但Model中不要强依赖View中的内容只能通过弱依赖,比方说可以有些Model是专门为某些View而设计的,但不能在Model中直接调用View逻辑,从Model中应该看不到任何Controller的逻辑。
强关联视图类型使用关键字必须包含ViewModel
先编写Model,需要编译一下,然后创建的controller,再action中创建强关联视图才能找到model类
进行分层结构设计:
Model类可以为实体类,对应增加一个逻辑类处理逻辑,再添加逻辑的controller,最后由controller添加对应的强关联视图。
在controller中尽量少用request和response。
使用部分类来验证输入的数据跟数据库是否重复:例如插入和更新:
Controller类:
动作名称选取器:
ActionName:使用这个标注的动作方法,在浏览器中需要输入actionname的指定值如:
浏览器需要输入PPOO方法才可以执行到write方法,还有要注意返回的view,默认是查找/View/Controller/PPOO而不是/View/Controller/Write,故如果要查找到相应的aspx文件的话,需要指定目录。
同名的Action主要用法如下:一个用于显示窗口的HTML还有一个用于接收窗口传送出来的值。
动作过滤器:
执行顺序:
VIEW数据
在aspx页面跳转方式:
在coNtroller中的页面跳转方式:
Return Redirect(“aspx”)OR return redirecttoaction(“action”,”controller”)
项目开发过程:
1先进行model类的开发:使用linq to sql类,把数据表拖进dbml文件中。
2进行controller开发,先定义功能框架,内部功能后面再定,注意好action filter的使用。
3进行view的开发,先进行模板以及跟窗口无关的页面的开发。
进行数据的验证,我们可以通过创建部分类来增加验证功能。:
Partial class member();
Forms的票证验证什么时候执行?即Application_AuthenticateRequest什么时候执行??
MVC中linq to sql的CURD:
INSERT:
using (LiuYanBan.Models.LiuYanBanDataContext db = new Models.LiuYanBanDataContext())
{
M1 = db.Member.Where(p => p.Account == member.Account).FirstOrDefault();
if (M1 != null)
{
ModelState.AddModelError("Account", "您ú注痢?册á的?账?号?已?经-被?使?用?,?请?重?新?设Θ?定¨另ⅷ?一?组哩?账?号?");
//return Content("注痢?册á失骸?败悒?);
return View(member);//返う?回?界?面?数簓据Y?
}
using (TransactionScope trans = new TransactionScope())
{
member.IsAdmin = false;
//member.CreateTime = DateTime.Now;
member.Password = EnCode(member.Password);
db.Member.InsertOnSubmit(member);
db.SubmitChanges();
}
}
return Content("注痢?册á成é功|");
}
Read(select ):
List<Models.Message> listMessage = new List<Models.Message>();
using (LiuYanBan.Models.LiuYanBanDataContext db = new Models.LiuYanBanDataContext())
{
var messagessql = from mes in db.Message select mes;
listMessage = messagessql.ToList();
}
return View(listMessage);
此处要注意把查询到的数据放入list中,否则当执行到view代码时,原本在controller中的使用connection资源链接的数据库一旦释放,将读不到查询到的数据messagessql 。
删除:
NorthwindDataContext ctx = new NorthwindDataContext();
Customer test1 = ctx.Customers.Single(c => c.CustomerID == "TEST1");
ctx.Customers.DeleteChanges(test1 );
ctx.SubChanges();
更新:
1、修改
public void Update(Product product)
{
var prod=db.Product.SingleOrDefault(a=>a.Id==product.Id);
if(prod!=null)
{
Name=product.Name;
Price=product.Price;
db.SubChanges();
}
}
ASP.NET MVC Framework支持四种不同类型的Filter:
1 Authorization filters – 实现IAuthorizationFilter接口的属性.
2 Action filters – 实现IActionFilter接口的属性.
3 Result filters – 实现IResultFilter接口的属性.
4 Exception filters – 实现IExceptionFilter接口的属性.
Filter的默认的执行顺序按上面的列表中顺序进行。如验证(authorization)Filter永远都是最开始执行的,异常(exception)Filter永远都是最后执行的,当然你也可以根据需要通过Order属性设定过滤器执行的顺序。
验证(authorization)filter用于实现在controller action上的验证和授权,如Authorize filter就是一个验证filter的例子;
Action filter包含一些逻辑,用于该action执行之前或者之后。比如可以使用一个action filter来修改action返回的view data;
Result filter包含一些逻辑,用于该action的view result执行之前和之后。比如可以修改一个view result在view被呈现到浏览器之前;
异常(Exception)Action用于处理异常信息,同样可以使用异常filter记录错误日志。
你同时可以创建自己的Action filter,比如说要实现一个自定义的验证系统,那么可能需要创建一个自定义的action filter,或者说当你需要改变controller action返回的view data的时候,也可以通过创建自定义action filter实现。
为了让用户更简单的创建一个自定义Action filter,ASP.NET MVC Framework提供了一个基类ActionFilterAttribute,这个类实现了IActionFilter和IResultFilter接口,并且继承了FilterAttribute类。从广义上来说,在ASP.NET MVC Framework中,任何实现filter的类型都是action filter。
ActionFilterAttribute类有以下的方法可以重写:
5 OnActionExecuting – 在controller action执行之前调用
6 OnActionExecuted – 在controller action执行之后调用
7 OnResultExecuting – 在controller action result执行之前调用
8 OnResultExecuted – 在controller action result执行之后调用
MVC引用文件路径:
默认系统会在站点目录下寻找。
数据库中的自增长变量,如果更新不及时进解决方案,就无法识别是自增长,会造成:验证数据的时候排除了自增长变量,但是插入数据库的时候还是会报错,此时需要在相应的models自增长字段中加上:IsDbGenerated=true
‘/UploadFile/qqq.mp4’
MVC项目中在项目属性的web属性中设置了“特定页”,会在启动的时候先启动特定页,再初始化global.asax文件.
程序中读取配置文件web.config,读取是根据Name来读取。对于文件路径的读取,会现在本项目根目录下读取,没有找到则会到调用该项目的另一个项目的根目录下读取。读取视项目类型而定,asp.net网页开发为web.config,winform为app.config。
MVC 之VC数据互传
V-->C:
1\建立强关联视图,submit提交表单(using(Html.BeginForm)),使用lablefor,textboxfor等关联model类,提交表单的在接收的action中使用关联的model类接收即可。
2\本质上是使用querystring,使用路由参数,如id,name传值。如
Html.ActionLink("尝¢试?参?数簓传?递蘗", "GetParams", new { name="dddd",age=24,price=22.3 })
在控制器的对应接收方法中,参数名称必须对上传过来的名称。
当不是强关联视图时,如:
3、使用ajax:
使用ajax可以使用post类型,也可以使用get类型,get类型会在url中显示参数,同时由于写入参数到html页面,会造成页面文件过大,一般情况下采用post,既不会在url中产生数据,同时也不会写入到html页面。
Second:
$(function(){
$(“#btn”).click(function(){
$.post(“/home/getparam”,
{
Text:”somestring”,
Number:23
},
Function(data)//接收后台处理后的返回数据处理
{
Alert(“接收成功”);
}
});
})
/home/getparam
Public actionresult getparam()
{
String text=requset[“Test”];
}
C-->V
1使用viewdata【】,tempdata[]
2使用强关联视图,关联的类可以再视图中使用”model。”来引用相应的属性。
3使用json
public JsonResult get_json()
{
IList<object> list = new List<object>()
{
new { name="aa",age=23,ismale=true},
new {name="dd",age=24,ismale=false}
};
return Json(list);
}
前端:
$(function(){
$.getJSON(“/home/get_json”,
Function(data)
{
$.each(data,function(index,p)
{
Var html=”<tr><td>”+p.name+”</td><td>”+p.age+”</td><td>”+
(p.ismale?”male”:”female”)+”</td></tr>”;
$(“tbody”).append(html);
});
});
});
VIEW视图引入命名空间,使用帮助类或者其他项目资源:
在view文件夹下的web.config进行配置,如果有多个要进行配置的话,可以放入全局的网站配置文件web.config中。
MVC内部登录API使用:
使用 FormsAuthenticationTicket
public static void CreateFormsTicket(string key, string role, bool isRemember)
{
//1):创洹?建¨一?个?验é证¤票±据Y
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, //版?本?号?
key, //与?票±据Y相à关?的?用?户§名?(在ú此?保馈?存?ID)
DateTime.Now,
DateTime.Now.AddMinutes(30),
false,//是?否?保馈?存?票±据Y
role //用?户§数簓据Y 保馈?存?用?户§角?色?
);
//2):加ó密ü票±据Y
string enTicket = FormsAuthentication.Encrypt(ticket);
//3): 创洹?建¨Cookie(辍?注痢?意癮Cookie名?称?,与?web.config 文?件t中D设Θ?置?的?一?致?)?
System.Web.HttpCookie cookie = new System.Web.HttpCookie(FormsAuthentication.FormsCookieName, enTicket);
//4:) 记?住?状痢?态?
if (isRemember)
{
cookie.Expires = System.DateTime.MaxValue;
}
//5): Cookie存?放?路·径?
cookie.Path = FormsAuthentication.FormsCookiePath;
System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
}
使用:if (!User.Identity.IsAuthenticated)
{
return Content("您ú尚未′登?录?,?请?先è登?录?!?");
}
MVC下载文件方式:
public FileStreamResult DownFile(string filePath, string fileName)
{
string absoluFilePath = Server.MapPath(System.Configuration.ConfigurationManager.AppSettings["AttachmentPath"] + filePath);
return File(new FileStream(absoluFilePath, FileMode.Open), "application/octet-stream", Server.UrlEncode(fileName));
}
方式二:
public ActionResult DownFile(string filePath, string fileName)
{
filePath = Server.MapPath(System.Configuration.ConfigurationManager.AppSettings["AttachmentPath"] + filePath);
FileStream fs = new FileStream(filePath, FileMode.Open);
byte[] bytes = new byte[(int)fs.Length];
fs.Read(bytes, 0, bytes.Length);
fs.Close();
Response.Charset = "UTF-8";
Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(fileName));
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
return new EmptyResult();
}
View调用:
<a href="/Document/DownFile?filePath=@item.Value&fileName=@item.Key">下载</a>
MVC上传文件
1页面使用<input type=”file” name=”fileContent”/>,同时Form标签属性要设置enctype = "multipart/form-data",即文件以二进制形式传送,否则上传不成功。
2改变上传文件4M的限制:webConfig节点<system.web>下的节点<httpRuntimemaxRequestLength="1048576" executionTimeout="3600" targetFramework="4.5" />
3后台上传submit接收方法,接收文件必须使用类HttpPostedFileBase,同时参数名必须与<input file>标签的name属性一致,否则提交上去的接收不到。
4后台保存上传文件路径:fileContent.saveAs(path);
5上传图片预览功能:使用第三方js脚本zxxFile.js
MVC 延迟加载:
EF延迟加载:就是使用Lamabda表达式或者Linq 从 EF实体对象中查询数据时,EF并不是直接将数据查询出来,而是在用到具体数据的时候才会加载到内存。
1)EF中的DbQuery对象操作数据库的时候发生延迟加载,而直接使用List<T>来接受对象时则不会;
2)延迟加载不会立即去查询数据库,而是在使用数据的时候才EF才会去查询数据库。
MVC使用EF的数据迁移功能:
首次为三步走:
1:Enable-Migrations -ProjectName XXX
2:add-migration -ProjectName XXX
3:update-database
以后做2、3步就好:
1先把修改的字段(model)写好,默认值可以再Seed方法中指定,假如初始为Null则不需要在Seed方法中定义。
2执行第一次的2、3步即可。注意第二步的命名,XXX必须与前面的命名一致,框架会根据命名递归找到以前的cs文件,最终合并编译成一个cs文件,命名自动从第二次开始变成XXX1,XXX2等递增上去。
Func是内置的定义委托方法的方式,省去了自定义的麻烦:Func<方法参数,方法返回值>;
MVC使用automapper
原因:在ORM中,与数据库交互用的Model模型是具有很多属性的。而当我们与其它系统(或系统中的其它结构)进行数据交互时,出于耦合性考虑或者安全性考虑或者性能考虑(总之就是各种考虑),我们不希望直接将这个Model模型传递给它们。
使用方法:
1写好model和其对应的modelDto类
2编写自定义profile类,要继承自profile类,重写属性profiName,重写方法configure(),重点在方法中注册映射creatMap<sourceClass,DesClass>();
3在程序运行初始化处进行注册(初始化)自定义profile类,使其运行。
报错:dll内部错误,一般是由于本地的model类与modelDto类对应上面出了问题,可能字段定义的类型不一致,还有一个就是可能没有在程序运行前注册profile。
MVC使用区域
1须有MVC.Area模板支撑,否则框架搭建不全。
2访问路由变为/Area/Controller/action
3使用Area中的一个控制器Index为默认页:
Glable的路由路径注册改为:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "BookBaseInfo", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "TestLearn1.Areas.BookStore.Controllers" }//针对Area设置默认访问路径
).DataTokens.Add("Area", "区域名称");
MVC前端对象数据转成json
1使用第三方js脚本:jQueryJSON.js,传之前先序列化对象:
var product1 = new Array();
product1[1] = { ID: 1, Name: "王而之" };
product1[2] = { ID: 2, Name: "选型号" };
var product = $.toJSON(product1);
2通过Ajax传到后台,接收类型为string:
public ActionResult GetJson(string product)
{
JavaScriptSerializer JSS = new JavaScriptSerializer();
List<Product> p = JSS.Deserialize<List<Product>>(product);
return Content("dddd");
}
重点在于使用JavaScriptSerializer 反序列化接收的字符串。
MVC级联查询
1使用EF三种导航加载方式:延迟加载,贪婪加载,显示加载
延迟加载会把导航属性延迟加载,在用到的时候才执行SQL语句;贪婪加载使用include句式,把相关表的数据一并查出;显示加载与延迟加载效果相似,区别未知。
使用贪婪加载时,include表名,假如是本类内定义有导航属性的,EF默认为inner join,如果要查询include(A)A中的相关表B(已在A中定义导航属性),则使用include(A.导航属性),此默认为left join。
2使用linq语法
Var data= From a in context.tb2 join b in context.tb3 on a.xid=b.xid select new
{ a.属性1,a.属性2,b.属性1,b.属性2};
目标SQL语句(多表 LEFT JOIN 查询)
SELECT id, name, jname, cname
FROM userinfo u
LEFT JOIN job j on u.job = j.jid
LEFT JOIN city c on u.city = c.cid
var list = (
from u in dc.userinfos
join j in dc.jobs on u.job equals j.jid into j_join
from x in j_join.DefaultIfEmpty()
join c in dc.cities on u.city equals c.cid into c_join
from v in c_join.DefaultIfEmpty()
select new
{
id = u.id,
name = u.name,
jname = x.jname,
cname = v.cname,
/*u1=u,x1=x,v1=v*/
//不要用对象的方式 因为对象可能为null那么对象.属性就会抛异常
}
).ToList();
注:使用linq 在代码中较为灵活,程序员可以控制使用各种内外链接,同时控制取什么样的字段属性,而使用EF的加载方式可以省略很多脚本语法麻烦,但是取出了查询表的所有字段数据,同时对于导航加载方式不熟的,无法知道框架生成的内外链接是怎么样的。
MVC增删改:
1使用EF
使用上下文的DBSet数据集find\delete\add\setvalues方法,同时操作完要使用上下文的saveChanges()方法,才能保存到数据库。
2使用linq:
上下文. 表数据集(dbset).insertonsubmit(entity)/deleteonsubmit(entity),修改直接对属性修改就好,最后也要进行上下文的submitchanges();
MVC验证机制
1一般在controller中进行验证:ModelState.IsValid
不通过的话一般返回View()验证机制中的错误信息将会显示到输入控件后面。如果验证一直为false,要检查提交的数据是否合法。这种验证机制方便程序员不必在后台写更多的验证代码。前台使用js进行验证。
MVC表单提交
1使用强关联类型,在提交后可以再后台使用对应的model类来接收。可以不使用@using(html.beginform()){},使用标签<form></form>也可,主要是字段需要用@html.textboxfor(),这样才能使强关联类对应上标签的name,后台才能用类接收。
2表单可以禁止提交:获取表单对象,对表单对象的提交事件:onsubmit中return false;即可。可以用在验证字段属性失败的时候禁止提交。
MVC分页
分页:
对查询到的数据dbset.asQueryable()转成Iqueryable,通过skip(页面数量*(页数-1)).take(页面数量)分页:
var query = db.Customer.OrderBy(customer=> customer.CustomerID)
.Skip(pageSize * (pageIndex - 1)).Take(pageSize);
MVC后台管理界面侧面菜单不变
1使用MVC母板应用,每一张页面都应用母板
2使用iframe:页面中先用标签<iframe>占位,通过js得到菜单<a>的点击事件,在点击事件中设置标签<iframe>属性src,src指向指定路由界面即可。结合菜单,通常指向菜单<a>标签的data-src属性值。
- MVC笔记
- MVC 笔记
- MVC笔记
- mvc笔记
- MVC 笔记
- MVC 笔记
- MVC笔记
- MVC笔记
- MVC笔记
- mvc学习笔记-mvc概述
- Spring MVC笔记
- mvc模式jsp笔记
- MVC笔记一
- MVC笔记二
- MVC WebCast学习笔记
- Spring3 MVC 笔记
- MVC 学习笔记一
- Java的MVC 笔记
- CS0016: 未能写入输出文件“c:\WINDOWS\Microsoft.NET\Framework\.。。”--“拒绝访问
- debian6下redis+keepalived故障自动切换
- IOS项目打包除去NSLog和NSAssert处理之阿堂教程
- ORACLE常见问题总结ing
- 智和信通SugarNMS无线微波网管解决方案
- MVC笔记
- pageContext,request,session,application的使用及区别
- oracle学习 用户命令相接
- python的日志logging模块使用总结
- php对xml进行简单的增删改查(CRUD)操作
- 设计模式与足球
- 计算两个日期间天数
- C++ Builder 如何创建饼图 TChart
- Hanganalyze分析会话阻塞—锁表