博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET MVC 4 (十二) Web API
阅读量:7239 次
发布时间:2019-06-29

本文共 10620 字,大约阅读时间需要 35 分钟。

Web API属于ASP.NET核心平台的一部分,它利用MVC框架的底层功能方便我们快速的开发部署WEB服务。我们可以在常规MVC应用通过添加API控制器来创建web api服务,普通MVC应用程序控制器根据用户请求的action方法返回ActionResult,而web api服务返回的则是json封装的模型数据。

在开始下面的内容前先给出相关类与接口的代码:

public interface IReservationRepository {        IEnumerable
GetAll(); Reservation Get(int id); Reservation Add(Reservation item); void Remove(int id); bool Update(Reservation item); }public class Reservation { public int ReservationId { get; set; } public string ClientName { get; set; } public string Location { get; set; } }public class ReservationRepository : IReservationRepository { private List
data = new List
{ new Reservation {ReservationId = 1, ClientName = "Adam", Location = "London"}, new Reservation {ReservationId = 2, ClientName = "Steve", Location = "New York"}, new Reservation {ReservationId = 3, ClientName = "Jacqui", Location = "Paris"}, }; private static ReservationRepository repo = new ReservationRepository(); public static IReservationRepository getRepository() { return repo; } public IEnumerable
GetAll() { return data; } public Reservation Get(int id) { var matches = data.Where(r => r.ReservationId == id); return matches.Count() > 0 ? matches.First() : null; } public Reservation Add(Reservation item) { item.ReservationId = data.Count + 1; data.Add(item); return item; } public void Remove(int id) { Reservation item = Get(id); if (item != null) { data.Remove(item); } } public bool Update(Reservation item) { Reservation storedItem = Get(item.ReservationId); if (storedItem != null) { storedItem.ClientName = item.ClientName; storedItem.Location = item.Location; return true; } else { return false; } } }

 

创建API控制器

在已有的MVC WEB应用中添加API控制器来创建WEB服务,VS的添加控制器对话框中可以选择创建API控制器,我们可以选择“Empty API controller”创建不包含任何方法的空API控制器,手工添加对应各个WEB服务操作的方法,一个完整的API控制类类似:

using System.Collections.Generic;using System.Web.Http;using WebServices.Models;namespace WebServices.Controllers {    public class ReservationController : ApiController {        IReservationRepository repo = ReservationRepository.getRepository();        public IEnumerable
GetAllReservations() { return repo.GetAll(); } public Reservation GetReservation(int id) { return repo.Get(id); } public Reservation PostReservation(Reservation item) { return repo.Add(item); } public bool PutReservation(Reservation item) { return repo.Update(item); } public void DeleteReservation(int id) { repo.Remove(id); } }}

当我们从浏览器访问 /api/reservation时得到的GetAllReservations方法封装的JSON数据,在IE10中得到的结果类似:

[{
"ReservationId":1,"ClientName":"Adam","Location":"London"}, {
"ReservationId":2,"ClientName":"Steve","Location":"New York"}, {
"ReservationId":3,"ClientName":"Jacqui","Location":"Paris"}]

如果是Chrome或者Firefox结果则是XML:

  
    
Adam
    
London
    
1
  
  
    
Steve
    
New York
    
2
  
  
    
Jacqui
    
Paris
    
3
  

这种区别源于浏览器提交的Accept头,IE10发送的Accept头类似:

... Accept: text/html, application/xhtml+xml, */* ...

表示IE10优先接受 text/html,接下来是application/xhtml+xml,如果前两者不可行, */*表示接受任何格式。Web API支持XML和JSON两种格式,但是优先使用JSON,所以IE10得到的*/*选择的JSON格式。Chrome发送的Accept头类似:

... Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 ...

Chrome优先接受application/xml,所以WEB API使用XML格式发送数据。

理解API控制器如何作用

在IE10中如果访问/api/reservation/3,得到的JSON数据类似:

{
"ReservationId":3,"ClientName":"Jacqui","Location":"Paris"}

这里得到的ReservationIdvalue=3的对象数据,这和MVC的路径映射很相似,实际上确实也是这样,API有自己的的路径映射,定义在 WebApiConfig.cs文件中:

using System.Web.Http;namespace WebServices {    public static class WebApiConfig {        public static void Register(HttpConfiguration config) {            config.Routes.MapHttpRoute(                name: "DefaultApi",                routeTemplate: "api/{controller}/{id}",                defaults: new { id = RouteParameter.Optional }            );        }    }}

这里的路径映射非常类似于MVC控制器的路径映射,但是所用的路径映射表和配置类都来自于System.Web.Http命名空间,Microsoft在这个命名空间复制了MVC的对应的类,这样做使得我们可以脱离MVC单独使用WEB API。这里注册的API路径映射最后在global.asax中通过WebApiConfig.Register(GlobalConfiguration.Configuration)注册到全局配置文件中。

和MVC控制器通过URL选择action方法不同,API控制器根据HTTP请求方法的不同来选择API控制器方法。API控制器方法的命名规则一般是HTTP方法作为前缀加上控制器的名称,比如GetReservation(这只是常规做法,DoGetReservation、ThisIsTheGetAction都是允许的),我们从浏览器访问/api/reservation所用的HTTP方法为GET,API控制器会查找所有包含GET的所有控制器方法,GetReservation和GetAllReservations都在考虑之类,但是具体选择哪个还参考了所带的参数,访问/api/reservation没有任何参数,因此API控制器选择了GetAllReservations,访问/api/reservation/3自然就选择了GetReservation。由此我们也知道PostReservation、PutReservation、DeleteReservation分别对应HTTP的Post、Put、Delete三种方法(WEB API的Representation State Transfer - REST)。

PutReservation方法命名多少有点不自然,我们更习惯称呼它为UpdateReservation,和MVC一样,System.Web.Http也提供一些特性可以应用于控制器方法:

public class ReservationController : ApiController {        IReservationRepository repo = ReservationRepository.getRepository();        public IEnumerable
GetAllReservations() { return repo.GetAll(); } public Reservation GetReservation(int id) { return repo.Get(id); } [HttpPost] public Reservation CreateReservation(Reservation item) { return repo.Add(item); } [HttpPut] public bool UpdateReservation(Reservation item) { return repo.Update(item); } public void DeleteReservation(int id) { repo.Remove(id); } }

这里通过HttpPost特性指定CreateReservation对应HTTP的POST请求,HttpPut指定UpdateReservation对应HTTP的PUT请求,MVC也有类似的特性,但是注意它们虽然同名但是定义在System.Web.Http命名空间。

使用WEB API

如同常规WEB服务,我们可以有多种方式来调用WEB API,比如windows form程序、其他ASP.NET应用程序,这里给出如何在当前MVC应用中利用javascript脚本来使用web api。

视图文件index.cshtml:

@{ ViewBag.Title = "Index";}@section scripts {        }

Reservations

Name Location
The data is loading

Add New Reservation

@{ AjaxOptions addAjaxOpts = new AjaxOptions { OnSuccess = "getData", Url = "/api/reservation" }; } @using (Ajax.BeginForm(addAjaxOpts)) { @Html.Hidden("ReservationId", 0)

@Html.Editor("ClientName")

@Html.Editor("Location")

}

Edit Reservation

Index.js:

function selectView(view) {    $('.display').not('#' + view + "Display").hide();    $('#' + view + "Display").show();}function getData() {    $.ajax({        type: "GET",        url: "/api/reservation",        success: function (data) {            $('#tableBody').empty();            for (var i = 0; i < data.length; i++) {                $('#tableBody').append(''                    + '' + data[i].ClientName + ''                    + '' + data[i].Location + '');            }            $('input:radio')[0].checked = "checked";            selectView("summary");        }    });}$(document).ready(function () {    selectView("summary");    getData();    $("button").click(function (e) {        var selectedRadio = $('input:radio:checked')        switch (e.target.id) {            case "refresh":                getData();                break;            case "delete":                $.ajax({                    type: "DELETE",                    url: "/api/reservation/" + selectedRadio.attr('value'),                    success: function (data) {                        selectedRadio.closest('tr').remove();                    }                });                break;            case "add":                selectView("add");                break;            case "edit":                $.ajax({                    type: "GET",                    url: "/api/reservation/" + selectedRadio.attr('value'),                    success: function (data) {                        $('#editReservationId').val(data.ReservationId);                        $('#editClientName').val(data.ClientName);                        $('#editLocation').val(data.Location);                        selectView("edit");                    }                });                break;            case "submitEdit":                $.ajax({                    type: "PUT",                    url: "/api/reservation/" + selectedRadio.attr('value'),                    data: $('#editForm').serialize(),                    success: function (result) {                        if (result) {                            var cells = selectedRadio.closest('tr').children();                            cells[1].innerText = $('#editClientName').val();                            cells[2].innerText = $('#editLocation').val();                            selectView("summary");                        }                    }                });                break;        }    });});

第一次访问index视图HTML界面装载完成后调用JS函数selectView("summary"),它显示ID=summaryDisplay的DIV块,隐藏其他的addDisplay、editDisplay块,然后通过调用JS函数getData(),getData使用GET方法向WEB API请求数据,返回的数据每个项目一行在表格中。summaryDisplay底部有Refresh、Add、Edit、Delete四个按钮,这些按钮的点击在“$("button").click(function (e)”处理;点击Refresh时调用getdata刷新数据;点击add时隐藏其他DIV块,显示addDisplay DIV块,这个DIV块创建一个AJAX表单,POST方法提交到API控制器的CreateReservation;EDIT按钮根据当前的选项从/api/reservation/{id} GET相应的对象后显示editDisplay DIV块,同时隐藏其他DIV块;点击editDisplay DIV块中的submitEdit按钮,JS使用PUT方法请求/api/reservation/{id}调用API控制器的UpdateReservation方法修改数据,完成后再次显示summaryDisplay DIV块,隐藏其他DIV块;点击delete按钮则是使用DELETE方法请求/api/reservation/{id}调用控制器方法DeleteReservation删除对象,完成后删除summaryDisplay DIV块中的相应行。

 

以上为对《Apress Pro ASP.NET MVC 4》第四版相关内容的总结,不详之处参见原版 。 

转载于:https://www.cnblogs.com/duanshuiliu/p/3709293.html

你可能感兴趣的文章
文件下载的ie11兼容性优化
查看>>
python写的分析mysql binlog日志工具
查看>>
MySQL 系列(二) 你不知道的数据库操作
查看>>
适配,
查看>>
缓存小姐 挡拆,网络请求 不同步 惹的祸,
查看>>
JS计算从某年某月某日到某年某月某日的间隔天数差
查看>>
使用PYTHON解析Wireshark的PCAP文件
查看>>
BarCodeToHTML(条形码toHEML)
查看>>
VC++文件监控 ReadDirectoryChangesW
查看>>
.net开发杂记
查看>>
《自动化技术中的进给电气运动》及学科学习笔记二
查看>>
所思所想目录导航
查看>>
spring中IOC模块特性
查看>>
HTML(HyperText Markup Language)
查看>>
Q&A: What is the difference between a Cash Dispersement or a Cash WithDrawal Transaction
查看>>
多线程顺序打印
查看>>
jsp九大内置对象之session和application
查看>>
codeforces 1C(几何题)
查看>>
Java集合的Stack、Queue、Map的遍历
查看>>
鼠标点击textarea后,在光标后追加内容
查看>>