问题
成都创新互联公司专注于企业网络营销推广、网站重做改版、玉泉网站定制设计、自适应品牌网站建设、HTML5建站、商城开发、集团公司官网建设、外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为玉泉等各大城市提供网站开发制作服务。
我们想快速启动一个 ASP.NETWeb API解决方案。
解决方案
APS.NET模板一开始就支持 ASP.NETWeb API。使用模板往我们的项目中添加 Controller,在我们解决方案的 Controllers文件夹上右键,选择“添加”->"Scaffolding"。
即用模式,可以从下面选择一个:
Web API2 Controller
Web API2 Controller with actions, using Entity Framework
Web API2 Controller with read/write actions
Web API2 OData Controller with action, using Entity Framwork
另外,带有属性路由的基架模板可以从 NuGet中下载。Install-Package Microsoft.AspNet.WebApi.ScaffolderTemplates.AttributeRouting.CSharp
工作原理
模板功能的全名是 ASP.NET模板(Scaffolding),他是一个基于T4模板的 ASP.NET代码生成框架。T4(Text Template Transformation Toolkit),是一个代码生成器模板,从 Visual Studio 2005开始 T4模板就已经 Visual Studio的一部分了。
Visual Studio 2013开始对模板的支持更加出色,允许我们快速生成 ASP.NET应用程序代码。在 Visual Studio 2013更新 2上,一些更具扩展性的功能点被添加进来,比如,模板的可定制化,这就让我们使用他生成代码的时候,更加灵活。
内建模板是被安装在Visual Studio安装文件夹中,我们可以在这里定制模板。例如,默认安装的情况下,模板是在
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates中。需要注意的是,修改任何模板之后,修改变更带来的影响就是全局的。如果想在每个项目的基础上自定义模板,可以通过下面的两种方式:
安装SideWaffle(sidewaffle.com),他是 Visual Studion模板管理的一个扩展程序。然后,使用常规的“添加”对话框,然后选择“Web”->“SideWaffle”->“ASP.NET Scaffolding T4”。将会在解决方案的文件夹中创建一个 “CodeTempplates”文件夹,包括所有全局模板的副本,就可以根据我们的项目需要来修改他。
手动的将所有全局模板复制到 ASP.NET项目中“CodeTemplates”(名字很重要)文件夹中,该文件夹是在项目的根目录中的一个文件夹。这些模板的副本中包含 C#和 VB.NET模板,但是,我们可以根据需要进行删减。要确保文件这些文件已经包含到项目中。
代码
让我们演示一个Web API Controller
Code-First使用基础模板处理的例子。
模型展示如列表1-13。
列表1-13. EF Code-First
public class Team{ public int Id { get; set; } public string Name { get; set; } public DateTime FoundingDate { get; set; } public string LeagueName { get; set; } }
添加完模型之后,我们在处理模板对话框的时候,需要重新编译项目。EF是依赖于我们项目应用程序 DLL的反射。然后,选择“添加”->“Scaffolding”->“Web API”->“Web API 2 Controller with actions,using Entity Framework”。对话框如图1-3。
图1-3.添加模板模板对话框。
可以按照图1-4的对话框来处理。必须许选择一个模型,他是通过全名来限定的(这有一个可用的下拉框,会展示这个项所有的类),Entity Framework DataContext(如果有的话,会在下拉框中展示,也可以直接在这里创建)也是通过全名来限定,并且默认的控制器名称也是和模型名称一样。我们可以检查“Use async controller actions”选择框来强制模板引擎生成异步 action和使用 EF DataContext的异步方法。
生成的Controller如清单 1-14(为了节省空间,没并没有贴出命名空间)。这是一个完全可以访问的 HTTP url,请求会被默认路由识别匹配。这个创建的 Action(POST)将会响应 201状态码给调用端,并包含一个指向最新创建资源定位的头。这个更新的 Action(PUT)甚至可能处理一个潜在的异常 DbUpdateConcurrencyException.
清单 1-14.通过模板生成使用 EF Action的一个 Web API Controller
public class TeamsController : ApiController{ private Apre***ecipesWebApiContext db = new Apre***ecipesWebApiContext(); // GET: api/Teams public IQueryableGetTeams() { return db.Teams; } // GET: api/Teams/5 [ResponseType(typeof(Team))] public async Task GetTeam(int id) { Team team = await db.Teams.FindAsync(id); if (team == null) { return NotFound(); } return Ok(team); } // PUT: api/Teams/5 [ResponseType(typeof(void))] public async Task PutTeam(int id, Team team) { if (!ModelState.IsValid) { return BadRequest(ModelState); } if (id != team.Id) { return BadRequest(); } db.Entry(team).State = EntityState.Modified; try { await db.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!TeamExists(id)) { return NotFound(); } else { throw; } } return StatusCode(HttpStatusCode.NoContent); } // POST: api/Teams [ResponseType(typeof(Team))] public async Task PostTeam(Team team) { if (!ModelState.IsValid) { return BadRequest(ModelState); } db.Teams.Add(team); await db.SaveChangesAsync(); return CreatedAtRoute("DefaultApi", new { id = team.Id }, team); } // DELETE: api/Teams/5 [ResponseType(typeof(Team))] public async Task DeleteTeam(int id) { Team team = await db.Teams.FindAsync(id); if (team == null) { return NotFound(); } db.Teams.Remove(team); await db.SaveChangesAsync(); return Ok(team); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } private bool TeamExists(int id) { return db.Teams.Count(e => e.Id == id) > 0; } }
现在,假设我们已经按照“工作原理”部分描述的方式,在我们的解决方案中添加了基架模板。但是,我们还是希望可以按照自己的方式定义它。例如,强制所有新建的 ASP.NET Web Api控制器类继承一个指定的基类,如清单 1-15所示。我们需要修改 CodeTemplates/ApiControllerEmpty文件夹中的 Controller.cs.t4文件,以确保每一个新的 Controller不再继承自 ApiController,而是成为 ApiBaseController的子类,这是一个在大项目中典型的需求,因为很多 Web API开发者喜欢采用自己的基类作为新的 Controller的基类。
清单1-15.通过模板强制新建的Web API Controller总是继承自 ApiBaseController
<#@ template language="C#" HostSpecific="True" #> <#@ output extension="cs" #> <#@ parameter type="System.String" name="ControllerName" #> <#@ parameter type="System.String" name="Namespace" #> using System;using System.Collections.Generic; using System.Linq;using System.Net; using System.Net.Http; using System.Web.Http; namespace <#= Namespace #> { public class <#= ControllerName #> : ApiBaseController { } }
如果现在来“添加”->“Scaffolding”->“Web API”->“Web API2 Controller Empty”,生成的代码如清单1-16所示,继承自 ApiBaseController而不是 ApiCnotroller。
清单1-16.根据自定义模板生成的Controller
Listing 1-16. A Controller Generated from the Customized Scaffolding Template
using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Http;using System.Web.Http;namespace Apress.Recipes.WebApi.Controllers { public class SampleController : ApiBaseController { } }
我们可以在更广泛的范围去使用这个定制化的技术,自定义命名空间,注入自己的服务,或者强制 action是异步的。
小提示不仅仅修改现有的,也可以添加新的,完全独立的模板。我们可以在学习更多官方的 .NET Web Development和Tools小组的小组的博客,请戳这里
https://blogs.msdn.microsoft.com/webdev/2014/04/03/creating-a-custom-scaffolder-for-visual-studio/