zoukankan      html  css  js  c++  java
  • [水煮 ASP.NET Web API2 方法论](1-5)ASP.NET Web API Scaffolding(模板)

    问题

      我们想快速启动一个 ASP.NET Web API 解决方案。

    解决方案

      APS.NET 模板一开始就支持 ASP.NET Web 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 代码生成框架。T4Text 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.0Common7IDEExtensionsMicrosoftWebMvcScaffoldingTemplates 中。需要注意的是,修改任何模板之后,修改变更带来的影响就是全局的。如果想在每个项目的基础上自定义模板,可以通过下面的两种方式:

    • 安装 SideWafflesidewaffle.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

    1
    2
    3
    4
    5
    6
    public class Team{
        public int Id { getset; }
        public string Name { getset; }
        public DateTime FoundingDate { getset; }
        public string LeagueName { getset; }
    }

      添加完模型之后,我们在处理模板对话框的时候,需要重新编译项目。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,请求会被默认路由识别匹配。这个创建的 ActionPOST)将会响应 201 状态码给调用端,并包含一个指向最新创建资源定位的头。这个更新的 ActionPUT)甚至可能处理一个潜在的异常DbUpdateConcurrencyException.

    清单 1-14. 通过模板生成使用 EF Action 的一个 Web API Controller

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    public class TeamsController : ApiController{
        private ApressRecipesWebApiContext db = new ApressRecipesWebApiContext();
        // GET: api/Teams    public IQueryable<Team> GetTeams()
        {
            return db.Teams;
        }
        // GET: api/Teams/5    [ResponseType(typeof(Team))]
        public async Task<IHttpActionResult> 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<IHttpActionResult> 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<IHttpActionResult> 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<IHttpActionResult> 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <#@ 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

    1
    2
    3
    4
    5
    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/

  • 相关阅读:
    PMP工具与技术篇--4.2.1-4 思维导图(数据表现技术)
    PMP工具与技术篇--4.2.1-3 决策--多标准决策分析技术
    PMP工具与技术篇--4.2.1-2 决策--投票(举手表决)
    PMP工具与技术篇--4.2.1-1 标杆对照技术(数据收集技术)
    PMP工具与技术篇--4.2.1 收集需求工具与技术总结
    PMP--4.2.1-2 需求跟踪矩阵
    PMP--4.2.1-1 需求文件
    PMP--4.2.1 收集需求--需求文件--需求跟踪矩阵
    PMP工具与技术篇--4.2 备案分析(数据分析技术)
    PMP--4.2-2 开发方法
  • 原文地址:https://www.cnblogs.com/shuizhucode/p/6060593.html
Copyright © 2011-2022 走看看