书Adam The Definitive Guide to HTML5

Adam Applied ASP.NET 4 in Context and Pro ASP.NET 4

到此为止,我们已经学了为什么ASP.NET MVC框架会出现,认识了建筑和潜在的设计目标。我们已经做了一个很好的测试驱动的实际的电子商务应哟那个。现在是时候打开钩子,揭示框架机制的所有细节。

在本书的第二部分,我们关注细节。从揭示一个ASP.NET MVC程序的结构,和应用请求处理管道开始。接着关注每个特性个体,如routing,controller,action,MVC view系统,带有领域模型的MVC的工作方式。

在这部分的最后两张,我们会看到如何在MVC程序中使用AJAX和jQuery。

概述MVC项目

在我们探索指定MVC特性之前,要提供一些额外的环境上下文。本章我们概述ASP.NET MVC应用的结构和本质,包括默认项目结构和必须遵循的命名规范。

1 使用VS MVC项目模板

当创建一个新的MVC3项目,VS让你选择Empty,Internet Application,Internet Application。Empty项目模板,会创建相对较少的文件和路径,给你最小的结构。

在这个对话框上,可以使用HTML5,微软已经开始添加HTML5到VS。我们忽略了这个选项,MVC框架。

当使用Internet或Intranet应用模板,可以创建单元测试作为VS解决方案的一部分。这两个模板的不同之处在于身份认证机制。

Folder or File Description Notes
/App_Data 这个路径是放置private data,如XML文件或数据库 IIS不会提供这个路径的环境上下文
/bin MVC程序编译过的装配放在这里,和GAC里没有的引用装配 IIS不会提供这个路径的环境上下文。不会再解决方案浏览器中看到bin路径,除非点击show all files按钮
/Content 存放静态上下的地方,如CSS文件和图片 这是个约定,但不是必须的。你可以把静态上下文放在任何地方
/Controllers 这是controller类的地方 这是约定。你可以把controller类放在任何地方,因为他们都被编译到同一个装配里
/Models 这是放置视图模型和领域模型类的地方,尽管简单的应用受益于在专用的项目中创建领域模型 这是约定。你可以定义你的模型类放在地方或单独的项目中
/Scripts 这个路径是放置JavaScript库。VS默认添加jQuery和Microsoft AJAX helpers 这是约定。你可以吧script文件放在任何位置,它们会作为其他类型的静态环境上下文
/Views 这个路径放置视图和局部视图,一般放置在它controller名字的文件家中 /View/Web.config文件预防IIS提供这些路径的上下文。View必须通过action方法被渲染
/Views/Shared 这个路径放置共享的布局和视图  
/Views/Web.config 这不是应用程序的配置文件。它包含views在ASP.NET中工作所必须的配置,防止IIS直接提供views  
/Global.asax 这是全局ASP.NET应用类,它的后端类Global.asax.cs是注册路由配置的地方。像配置任何代码一样运行一样,能够在程序初始化时运行,关闭,或当未经处理的异常发生 Global.asax文件在MVC应用中,和Web Form应用中的角色一样
/Web.config 这是应用的配置文件。 与Web Form应用中的角色一样

MVC应用部署拷贝文件夹结构到web server。处于安全的原因,IIS不提供Web.config,bin,App_code,App_GlobalResources,App_LocalResources,App_WebReferences,App_Data,App_Browsers这些路径中的文件。IIS也会把.asax ,.ascx,.sitemap,.resx,.mdb,.mdf,.ldf,.csproj过滤掉。如果想要调整项目的结构,必须确保不在URLs中使用这些名字和扩展名。

Folder or File Description
/Areas 区域,是把一个大应用分隔成小片的方法。
/App_GlobalResources
/App_LocalResources
这些文件包含本地化Web Forms页面所需要的资源文件
/App_Browsers 这个文件夹包含.browser XML文件,它是描述如何识别指定的web浏览器,已经这个浏览器能干什么
/App_Thems 这个文件夹包含Web Forms主题,包含.skin文件,影响Web Forms如何控制渲染
   

除了/Areas,表中的其他项是核心ASP.NET平台,和MVC应用不是特别有关。

1.1 使用Internet和Intranet应用控制器

这两个模板都有HomeController,它可以渲染Home页面和About页面。这些页面使用默认布局生成。

Internet应用模板还包含AccountController,它允许访问者注册,登录。它使用表单身份验证,保持用户是否登录的轨迹。它使用ASP.NET核心会员设施,记录注册用户的列表。会员设施会在第一次有人尝试着注册或登录时,在/App_Data文件夹试着创建SQL Server Express基于数据库的文件。如果没有安装并且运行SQL Server,这样会在长时间停顿后失败。AccountController也有actions和views,可以让注册用户改变密码。Intranet Application模板省略AccountController,因为它期望使用Windows domain/Active Directory基础设施管理账户和密码。

1.2 理解MVC约定

在MVC项目中,有两种类型的约定。第一种只是建议你如何设置项目的结构。例如,它惯例地将JavaScript文件放在Scripts文件夹。这是其他MVC开发人员期待找到它的地方,也是VS为新MVC项目放置初始化JavaScript文件的地方。但是你可以重命名Scripts文件夹,甚至完全删除它,放置scripts到任何地方。这不会阻碍MVC框架运行。

另一个类型的约定来自约定大于配置的原理。这意味着不用明确配置controller和views的关联。只需要一个明确的controller名字就行了。

所有约定都能使用自定义视图引擎改变。

1.2.1 以下是控制器类的约定

Controller类的名字必须以Controller结尾,如ProductController。当从MVC route或HTML helper方法参照controller,需要制定名字的第一部分,如Product,DefaultControllerFactory类会自动在名字后附加Controller,并开始寻找controller类。可以通过创建自定义的IControllerFactory接口的实现,改变这个行为。

1.2.2 以下是视图的约定

视图和局部视图应该在它关联的控制器名字的文件夹下,如ProductController类的关联视图应在/View/Product文件夹下。

MVC框架期望action方法的默认视图,应以它的名字命名。例如,List action方法的关联视图应叫List.cshtml,如果使用ASPX视图引擎是List.aspx。

默认视图是用来当你在action方法中调用View方法,返回结果。

return View();

我们指定一个不同的视图,使用名字

return View("MyOtherView");

我们没有包含文件的扩展名,或视图的路径。MVC框架会试着找到这个视图,使用文件名和视图引擎的扩展名,默认是Razor和ASPX视图引擎。

当查找一个视图,MVC框架会查找控制器命名的文件夹,然后找/Views/Shared文件夹。这意味着我们可以在不同的controller中使用/View/Shared文件夹中的同一个view,并依赖框架找到他们。

1.2.3 以下是布局的约定

布局的命名约定,是在文件名前加_下划线前缀,这起源于WebMatrix,另一个使用Razor的。布局文件放在/Views/Shared文件夹。VS创建一个叫做_Layout.cshtml的布局,作为初始化项目模板的一部分。这个不是被默认应用到所有的视图,通过/Views/_ViewStart.cshtml文件。

如果不想让默认布局应用到视图,可以更改_ViewStart.cshtml的设置,指定另一个布局。

@{
Layout ="~/Views/Shared/MyLayout.cshtml";
}
@{
Layout =null;
}

2 调试MVC应用

我们会展示如何设置调试,创建断点,在程序和单元测试中运行调试。

2.1 创建项目

创建新项目,使用Internet应用模板,选中创建单元测试。在编译模式中选择调试模式。调试的快捷方式是F5。如果选择修改Web.config文件,编译选项会更新Web.config文件中的debug属性的值为true。

...
</compilation>

不要在没有禁用debug设置的情况下,部署程序到生产环境。

2.2 调试

一个未处理的异常会导致调试中断。通过使用try..catch块,可以使一个异常变为处理过的。异常处理是非常有用的编码工具。它用来代表一个方案:一个方法无法完成它的任务,需要通知他的调用者。未处理的异常很坏,它代表一个我们意料之外没有处理的条件。

2.3 使用Edit和Continue

VS调试特性中最有意思的一个是编辑和继续。当调试器终端,你可以编辑你的代码,然后继续调试。VS重编译你的程序,重建程序在调试器终端这一刻的状态。

2.4 启用编辑和继续

我们需要在两个地方启用编辑和继续

  • 在VS工具菜单的调试器选项,有编辑和继续的节点,保持启用被选中。
  • 在项目属性中,点击Web节点,确保启用编辑和继续被选中。

2.4.1 编辑并继续

当弹出异常后,在exception helper窗口上点击Enable editing link,改变代码,从调试菜单中选择Continue。

在这时,VS重编译我们的程序,使得我们的改变被包含在构建进程,重新启动执行,重新创建导致异常的状态,然后保持正常。浏览器收到结果的渲染。

没有编辑并继续,我们要停止程序,改变代码,编译横须,重启调试。然后使用浏览器重复导致调试终端的步骤。这是避免这最重要的最后一步。复杂的漏洞可能需要很多步骤,这样可以节省程序员的事件和头脑清醒。

3 项目范围的依赖性注入

在下面的章节,我们会看到多少不同的方式,MVC框架为你的扩展提供支持,自定义如何被请求服务。这些都被定义为接口的实现,或一个基类的派生。

我们已经见过自定义MVC框架的例子。我们创建DefaultControllerFactory类的派生类NinjectControllerFactory,为了能够使用Ninject创建controller,来管理DI。我们最终能够在程序中使用DI,但是比我们理想的,多了一些代码复制和Ninject kernels。

当MVC框架需要创建一个类的实例,它会调用System.Web.Mvc.DependencyResolver类的静态方法。我们可以添加DI贯穿一个MVC程序,通过实现IDependencyResolver接口,并通过DependencyResolver注册偶们的实现。通过这种方式,无论何时框架需要创建一个类的实例,它都会调用我们的类,我们可以调用Ninject来创建这个对象。

我们没有在SpotrsStroe中强化DI,因为我们只想要展示添加DI到控制器。下面展示如何实现IDependencyResolver接口。

publicclass NinjectDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver()
{
kernel =new StandardKernel();
AddBindings();
}
publicobject GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
public IBindingToSyntax<T> Bind<T>()
{
return kernel.Bind<T>();
}
public IKernel Kernel
{
get { return kernel; }
}
privatevoid AddBindings()
{
Bind<IProductRepository>().To<EFProductRepository>();
Bind<IAuthProvider>().To<FormsAuthProvider>();
EmailSettings emailsSettings =new EmailSettings
{
WriteAsFile =bool.Parse(ConfigurationManager.AppSettings["Email.WriteAsFile"] ??"false")
};
Bind<IOrderProcessor>().To<EmailOrderProcessor>().WithConstructorArgument("settings", emailsSettings);
}
}

这个类很简单。前两个方法是当MVC框架需要类的一个新实例时被调用,我们简单地调用Ninject kernel传递给请求。我们添加了Bind方法,所以可以从类外面添加绑定。这完全是可选的,因为我们也包含AddBindings方法,从构造器中被调用。

现在可以删除NinjectControllerFactory类,并在Global.asax中的Application_Start方法注册更一般的NinjectDependencyResolver类。

DependencyResolver.SetResolver(new NinjectDependencyResolver());

通过这些设置,我们将Ninject放到了MVC程序的心脏。偶们可以继续改进MVC框架的这个扩展点,但我们不在需要,因为我们想做的知识介绍DI到请求管道的一些部分。

【Pro ASP.NET MVC 3 Framework】.学习笔记.11.ASP.NET MVC3的细节:概览MVC项目的更多相关文章

  1. Pro ASP.NET MVC 5 Framework.学习笔记.6.4.MVC的必备工具

    2.5.创建链式依赖 当你请求Ninject创建一个类型,它检查该类型的依赖是否声明.它也会检查该依赖是否依赖其他类型.如果这里有附加依赖,Ninject自动解决他们,并创建请求的所有类的实例.正是由 ...

  2. Pro ASP.NET MVC 5 Framework.学习笔记.6.3.MVC的必备工具

    每个MVC程序员的军火库中,都有这三个工具:一个依赖注入(DI)容器,一个单元测试框架,一个模拟工具. 1.准备一个示例项目 创建一个ASP.NET MVC Web Application的Empty ...

  3. ASP.NET MVC Web API 学习笔记---第一个Web API程序

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...

  4. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

  5. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  6. ASP.NET Core Web开发学习笔记-1介绍篇

    ASP.NET Core Web开发学习笔记-1介绍篇 给大家说声报歉,从2012年个人情感破裂的那一天,本人的51CTO,CnBlogs,Csdn,QQ,Weboo就再也没有更新过.踏实的生活(曾辞 ...

  7. 一起学ASP.NET Core 2.0学习笔记(二): ef core2.0 及mysql provider 、Fluent API相关配置及迁移

    不得不说微软的技术迭代还是很快的,上了微软的船就得跟着她走下去,前文一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx.superviso ...

  8. MVC缓存OutPutCache学习笔记 (二) 缓存及时化VaryByCustom

    <MVC缓存OutPutCache学习笔记 (一) 参数配置> 本篇来介绍如何使用 VaryByCustom参数来实现缓存的及时化.. 根据数据改变来及时使客户端缓存过期并更新.. 首先更 ...

  9. MVC缓存OutPutCache学习笔记 (一) 参数配置

    OutPutCache 参数详解 Duration : 缓存时间,以秒为单位,这个除非你的Location=None,可以不添加此属性,其余时候都是必须的. Location : 缓存放置的位置; 该 ...

随机推荐

  1. android JSONArray JSONObject 字符串转json数组 遍历json对象

    String json = "{''data'':[{''name'':''Wallace''},{''name'':''Grommit''}]}"; StringBuffer m ...

  2. 单源最短路径——Dijkstra算法学习

    每次都以为自己理解了Dijkstra这个算法,但是过没多久又忘记了,这应该是第4.5次重温这个算法了. 这次是看的胡鹏的<地理信息系统>,看完之后突然意识到用数学公式表示算法流程是如此的好 ...

  3. WW多线程和锁

    问题: WorldWind中是双线程的,一直忽略了多线程中数据共享,修改数据会产生问题.可是在WW中并没有看到锁的东西. 还有就是动态释放内存的问题.因为采用D3D的C#封装库不可避免涉及COM对象的 ...

  4. shellinabox安装

    Shell In A Box(发音是shellinabox)是一款基于Web的终端模仿器,由Markus Gutschke开辟而成.它有内置的Web办事器,在指定的端口上作为一个基于Web的SSH客户 ...

  5. javaScript函数与闭包

    js中函数也是对象,具有一切对象的特征,可以作为表达式给变量赋值,可以作为函数的形参,或者函数的返回值,函数内可以嵌套函数等等,函数内以声明方式定义的函数是局部函数,用表达式声明的函数则由赋值变量的性 ...

  6. 音乐播放器 AVAudioPlayer、定时器、UISlider

    #import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @interface ViewController ...

  7. 数据库调优过程(一):SqlServer批量复制(bcp)[C#SqlBulkCopy]性能极低问题

    背景 最近一段给xx做项目,这边最头疼的事情就是数据库入库瓶颈问题. 环境 服务器环境:虚拟机,分配32CPU,磁盘1.4T,4T,5T,6T几台服务器不等同(转速都是7200r),内存64G. 排查 ...

  8. log4net面面观之工作原理

    转自:逗逼的博客:http://itrust.cnblogs.com/archive/2005/01/25/97225.html 要知道Log4net究竟是咋干活的,咱们可以从下面这个脉络简图入手.你 ...

  9. C++字符串(String)

    字符串的声明: string s; string str="abcdefg"; char ch[]="abcdefg"; //使用string类型初始化另一个s ...

  10. [transferred] javascript exception handling.

    my error handling clause: window.onerror = function (errorMessage, scriptURI, lineNumber, columnNumb ...