简介
开始接触MVC5,学习笔记从这里起步。
这个东西从没接触过,上网搜搜,到处找找,一时雾里看花。对于PHP web 的开发者,MVC这几个字绝对唬得住你。
由于之前用asp .net ,在转到mvc十分不习惯,没有了用户控件,没有了服务器控件。没有了各种绑定事件,没有了ajax控件。可是却又很多相似的地方,如布局的模版(能继承)。更加的灵活,更加的方便。
1.就如HTML一样,mvc5里使用的是后缀为.cshtml的文件格式(需要先编译成 .html),也支持.html。几乎和HTML一样。
2.页面代码里也有Razor语法 @{...},满足使用。
3.正如HTML一样,样式和效果可以直接使用CSS样式和JS。无需像ASP .NET 一样挠头。
4.first coder (EF),可以轻松访问数据库。
对于新的框架,我这个新手第一步必须要了解的是它的架构。
MVC5就像它的名字一样是MVC模式的,可是在网上却没有找到人把他作为MVC来开发,更多的是把他当成了一个View层(或则Controller层与View层),其他层用其他项目来实现。
所以在微软的世界里面,叫什么名字不重要,到底是干什么的才重要,所以不要能过于的纠结名字。
MVC5项目大体的架构
在网上学习很很多人的文章,都是将MVC5项目作为最上面的一层的子项目。而整个工程内包含多个不同层级的项目。
最左边的mvc5项目,中间的是BLL,右边的是DAL。其中关于MVC的这些名字不要在意这些细节,可以将其理解成三层架构,而mvc只是其中视图层的一种模式。
另外两个项目不属于mvc5的范畴,这里不做记录。
直到现在对于mvc5都还是概念上的印象,用vs2013新建一个mvc5的项目,了解项目的结构和它的工作原理是开展代码编写之前的必要工作。
App_Data:这个文件夹就是来放本地的存储文件的,比如数据库文件,xml数据文件之类的
App_start:
其中 BundleConfig是注册项目中要用到的CSS,JS文件的,一定不要忘记注册了再到代码里引用了使用。FilterConfig是一个删选器。RouteConfig是一个路由器,我们在项目里使用相对路径访问,这个可以暂时不用管它。Startup.Auth包含一些安全认证和认证方式。
Content:这个文件夹用来存放一些静态的文件,比如CSS,Image。
Controllers:这里面的文件都是叫做控制器,必须以Controller结果,所以看文件名的时候可以选择性忽略Controller。这里的控制器与mvc架构中的差不多:
- 做与视图(网页文件)的映射。每一个Controller都与Views文件里的一个同名(没有“Controller”)文件夹映射,当使用“~/xxx1/xxx2”这样的相对路径访问跳转到指定视图的时候,先去寻找这个“xxx1”控制器,然后在里面找有没有一个叫“xxx2”的方法,这个方法用来返回对应路径的视图文件。所以在对应控制器的视图路径下新建视图后,一定要去对应控制器里添加一个与视图同名的返回的方法。
- 做界面数据的接口,我们界面上一般采用流行的ajax来同步数据。所以在不实用mvc5自己的数据绑定之后,controller成为一个可以被js调用的方法接口,我们在controller提供能够返回数据的方法,在界面层使用js调用这些方法,再显示到界面上,就能达到ajax的效果。
Fonts:web项目显示中可能会用到的一些字体文件。
Models:这就是mvc5中的m了,模型。但是我们更喜欢喊他真实的名字实体集。其实它跟模型木有半毛钱关系,不是用来查询数据库、封装事务的,而是放置一些界面需要使用的数据实体。
Scripts:JS就放在这里面。记得到前面的BundleConfig注册哟。。。
Views:视图了,这个是真正的视图,就是存放我们的前端文件的地方。具体在下节打字。
了解了项目的结构之后,我们就能清晰的知道将对应的代码放在哪里,怎么让界面跑起来,怎么给界面传输数据了。
MVC5前端代码结构
在翻阅Views这个文件夹的时候,有些看懂有些看不懂,雾里看花。但是万事怕研究,分开来看看。
它山之石,可以攻玉。从Django到ASP .net ,我熟悉了他们关于模版的设计思维,我也不小心被俘虏了。所以到了mvc中我还是在努力寻找如何编写模版。
看懂了的,新建文件的时候我发现了能新建的页面类型。
布局页,分布页,带布局的视图页/不带布局的视图页
看到这些个就笑了,怀着学习的心态,最好的办法就是把所有的都新建一遍看看。结果发现全都是.cshtml结尾的,没有asp .net 布局文件(.master)、视图文件(.aspx)、用户控件(.ascx)那么的复杂。
具体来看看不同类型下的模版文件初始内容有何不同。
1.布局页(模版):
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
和传统html没什么两样,有些特别之处——Razor语法:@ViewBag.Title 充当标题的标记,编译时替换。 @RenderBody() 代表着继承布局模版的视图内容 。动手编写你自己的模版吧。
2.分布页(分片、分部分的意思):没有任何内容,从研究其他项目内视图发现,这里面多放置需要逻辑判断显示的不同内容等界面逻辑代码。如需要引用,@Html.Partial("_XXXPartial") 这样在你的代码中使用那个分片页。
3.带模版的视图页/不带模版的视图页(我这里模版就是布局,讲习惯了):
@{
Layout = "~/Views/Shared/_LayoutNavigation.cshtml";
ViewBag.title = "测试页面";
}
文件抬头就是引用需要使用的布局页面,反正模版就是占好的坑,一个一个的去填就是了。
我发现,布局与分布视图都是以下划线开头,取私有固定之意,为模版。布局都已Layout结尾,分片都已Partial结尾。
从本质上来说这些不同类型的文件根本没有任何区别,你可以新建一个空的项目编写任何一个类型的文件,只要你的命名上规范(为的你能一眼分清楚它是干嘛的),格式上按照不同的来,模版引用模版,视图引用模版,视图包含分布,模版包含分布。形成了一个树形的结构,全看我们怎么写。
这里特意说明,子模版抬头引用不必说,其中要标记引用视图的内容位置和父模版一样用 @RenderBody() 标记就是了。
还有些不懂,翻遍了项目,没搞明白 _ViewStart.cshtml 这个视图是在何处定义声明的。因为它的存在,你可以不在你的视图中引用任何布局模版,而默认使用 _ViewStart.cshtml 中引用的布局模版。当然你引用的话,就不会使用它默认的布局模版。
开发WebAPI与AJAX使用(JQuery)
先说下AJAX,异步数据传输。它不是一个东西,而是一种技术(效果)。可以通过不同的方式来实现,比如js手工,比如JQ调用方法,还比如更高一级的封装再调用。用到的也是HTTP REST方法。下面用的是JQ的Get()方法。
mvc5的访问规则是按照RouteConfig中规定的URL格式来访问。如:
url: "{controller}/{action}/{id}";
它会先去寻找对应名字的Controller,当然不算后缀“Controller”。然后通过Controller里有没有action的同名方法,若有,则执行。没有就访问未知。
普通的mvc5包含视图控制器,继承于Controller。它既能控制界面层访问,也能控制数据访问,不过没人这么玩儿。只拿它做界面视图的映射。
public class XXXXXController : Controller//“XXXXX”就是控制器的名字,当然文件名后面还要加上Controller。
而我们需要与界面进行数据交互、ajax。肿么办?当然网上神马资料的都是说用models,controllers肿么肿么用。太复杂。。。。我们使用ajax与webapi。
我们只需要在建立mvc5项目的时候,给它把webAPI勾上。干嘛的呢?专门做数据访问的API的。URL访问方式在WebApiConfig文件里面就能看到,也可以和RouteConfig一样自己修改访问方法。看看我自建TestWebApi类的定义:
public class TestWebApiController : ApiController
webapi 的控制器是继承于“ApiController”的,他和RouteConfig一样,都有支持默认的REST方法。通过URL访问这些方法的时候,会根据你的请求类型自动解析,而不用带上方法名。
但是默认的方法不好用,我想自己定义方法。就要用上标记,一个是动作的名字,一个是相应的请求类型。不标记就不会被访问。
[ActionName("GetPersons")]
[HttpGet]
public string GetPersons()
{
return "test string";
}
注:URL路由是使用的字典匹配而无需同名,所以取名要谨慎。有同名前缀神马的,一定要小心。如有个一方法叫Get();
这样一个web api就做好了,接着需要的就是被访问了。转到界面上,我的js代码:
$.getJSON("http://localhost:XXXX/api/[ControllerName]/[CustomerAction]", [Args], function (data) {
SetText(data);
} );
按照WebApiConfig的访问规则完成URL,根据你需要访问的Action有无方法,来确定Args是空还是有。若有,则可以用Object类实例化一个对象,不管你是一个参数,还是几个。设置Object对象与你Action方法的同名属性的值,将这个Object对象当作参数传过去就行了。如我有与一个叫key的参数:
var object = new Object();
object.key = "23w23232323";
JQ的get方法第三个参数就是成功需要回调的函数,而且是函数体,不能传函数名。如果想要回调某个已经编写好的函数,则定义一个匿名函数,在其中调用你想要调用的方法,如上面代码所示。参数就是访问的webAPI方法的返回值,随便定义变量明。
接着就是拿到数据控制显示的事了。。那是另一个故事了。