赞
踩
Webapi也是一种服务,是属于服务端的,供客户端调用,类似webservice,但是与mvc请求方式不一样(MVC通过路由 controller/action请求),Webapi通过不同的HTTP请求(get(查询)、put(更新)、post(增加)、delete)来表达不同的动作(CRUD),只关注数据。它非常适合构建移动客户端服务,显示端可以用H5等进行创建。
声明:本小结叙述来微软mvp杨旭的草根专栏https://www.cnblogs.com/cgzl/p/11814971.html
MVC(Model-View-Controller)是一种主要用来构建UI的架构模式。对于MVC模式其实有很多种解释存在,但是无论那种解释,它们都会强调松耦合和关注点分离(separation of concerns)。
也是由于这两点的存在,程序的可测试性会大大提高,程序各部分的可复用性也很高。
更多关于MVC的介绍,可以看一下微软的官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/overview?view=aspnetcore-3.0
注意:MVC不是一个完整的应用程序架构,我认为它主要是用在展示层。所以实现UI就是MVC的一部分工作。
我认为API同样可以看作是UI,它就是为API消费者所提供的UI。
让我们把MVC的三部分分别对应到API:
Model,它负责处理程序数据的逻辑。这里的Model可以包含在当前级别获取从存储获取数据的逻辑。但是有一些Model不包含任何逻辑,例如API所使用的DTO(Data transfer objects),这类的Model会被串行化到响应的body里面。
View,它是程序里负责展示数据的那部分。在构建API的时候,View就是数据或资源的展示。现在通常使用JSON格式。
Controller,它负责View和Model之间的交互。包括处理用户输入,用API的术语来讲,和API交互的“用户”就是指API的消费者,这类用户通常是另一个程序,例如Angular的SPA程序。
Controller和View依赖于Model,Controller依赖于View,这也是分离的一个好处。
换句话说,Controller会选取适当的View来展现给用户,并一同把用户请求的Model数据带回去。
当API消费者发出请求的时候,在Controller上面的Action将会被触发,Controller会把接收到的输入数据发送给负责业务处理逻辑或数据访问逻辑的那部分程序。然后Controller会把Model返回给View,这里的View就是资源的展示(通常是JSON格式)
创建ASP.NET CORE webapi默认项目:WebAPIDemo.
Controllers文件夹下有一个ValuesController.cs,默认代码如下:
- namespace WebAPIDemo.Controllers
-
- {
-
- [Route("api/[controller]")]
-
- [ApiController]
-
- public class ValuesController : ControllerBase
- //.Net Core2.0(VS2017)下默认继承自Controller,且上面没有打[ApiController]特性
-
- {
-
- // GET api/values
-
- [HttpGet]
-
- public ActionResult<IEnumerable<string>> Get()
-
- {
-
- return new string[] { "value1", "value2" };
-
- }
-
- // GET api/values/5
-
- [HttpGet("{id}")]
-
- public ActionResult<string> Get(int id)
-
- {
-
- return "value";
-
- }
-
- // POST api/values
-
- [HttpPost]
-
- public void Post([FromBody] string value)
-
- {
-
- }
-
- // PUT api/values/5
-
- [HttpPut("{id}")]
-
- public void Put(int id, [FromBody] string value)
-
- {
-
- }
-
- // DELETE api/values/5
-
- [HttpDelete("{id}")]
-
- public void Delete(int id)
-
- {
-
- }
-
- }
-
- }
运行结果:
启动运行结果如上图所示,得到了服务端数据,这说明就使用了webapi服务。请求格式
https://localhost:44323/api/values
是如何定位到Get方法的呢?
https://localhost:44323/是域名 api是固定的格式 values是控制器
是如何定位到Get方法呢?因为通过URL方法访问默认就是Get请求,默认就去请求Get方法或者以Get开头的方法名。
那么是如何定位到有参数Get方法呢,如下图请求,则请求到的是到有一个参数的get方法,因为传入一个参数1
在ASP.NET Core MVC中,WebAPI就是其中一项功能子集,可以直接使用MVC的特性及路由等功能。
- public class ResultViewModel
- {
- public int Id { get; set; }
- public string StuName { get; set; }
- public string Title { get; set; }
- public string Discription { get; set; }
- public string Type { get; set; }
- public string Attachment { get; set; }
- }
VS2019/2017创建的时候会默认加上特性路由[Route(“api/[controller]”)],将其中的[controller]改成Result,然后添加对应的操作,分页查看Result,根据id查看指定Result及添加Result。逻辑与Controllers文件夹中的ResultController大致相同。
代码如下:
- [Route("api/Result")]
- [ApiController]
- public class ResultAPIController : Controller
- //此处默认是继承ControllerBase,继承这个话ViewBag没有用哦
- {
- //这里注入了两个依赖的服务,具体的功能可以不去管
- //一个是管理成果的各种信息,管理一个是类型
- private IResultRepository _resultRepository;
- private IResultTypeRepository _resultTypeRepository;
- public ResultAPIController(IResultRepository resultRepository,
- IResultTypeRepository resultTypeRepository)
- {
- _resultRepository = resultRepository;
- _resultTypeRepository = resultTypeRepository;
-
- }
- // GET: api/result 查找
- [HttpGet]
- public IActionResult Get(int pageindex = 1, int pagesize = 5)
- {
- var results = _resultRepository.PageList(pageindex, pagesize, out int pagecount);
- ViewBag.PageCount = pagecount;
- ViewBag.PageIndex = pageindex;
- var resultList = results.Select(r => new ResultViewModel
- {
- Id = r.Id,
- StuName= string.IsNullOrEmpty(r.Password) ? r.StuName : "",
- Title = string.IsNullOrEmpty(r.Password) ? r.Title : "加密内容",
- Discription = string.IsNullOrEmpty(r.Password) ? r.Discription : "",
- Attachment = string.IsNullOrEmpty(r.Password) ? r.Attachment : "",
- Type = r.Type.Name
- });
- return Ok(resultList);//不能返回View,返回json
- }
- //Get api/result/5 根据条件查找
- //Get api/result/5?password=123
- [HttpGet("{id}")]
- public async Task<IActionResult> Detail(int id, string password)
- {
- var result = await _resultRepository.GetByIdAsync(id);
- if (result == null)
- {
- return NotFound();//返回404错误
- }
- if (!string.IsNullOrEmpty(result.Password) &&
- !result.Password.Equals(password))
- {
- return Unauthorized();//返回401错误,未授权
- }
- var resultView = new ResultViewModel
- {
- Id = result.Id,
- StuName=result.StuName,
- Title = result.Title,
- Discription = result.Discription,
- Attachment = result.Attachment,
- Type = result.Type.Name
- };
- return Ok(resultView);
- }
- //POST api/result 增加
- //方法参数前加[FromBody] 标识,表示该参数值应该从请求的Body中获取,而不是从URL等其他地方中获取
- [HttpPost]
- public async Task<IActionResult> Post([FromBody] ResultModel model)
- {
- await _resultRepository.AddAAsync(new Result
- {
- StuName = model.StuName,
- Title = model.Title,
- Discription = model.Discription,
- Create = DateTime.Now,
- TypeId = model.TypeId,
- });
- return Content("ok");
- }
- }
运行程序,访问地址:http://localhost:5001/API/Result(不一定是5001,下同,看下图),即可获取第一页的Result数据,数据格式为json(有些浏览器提示为下载文件),结果如下图所示。pageindex参数直接加在访问地址后面,如http://localhost:5001/API/Result?pageindex=2,这代表访问第二页数据。
Get http://localhost:5001/API/ Result /1获取Id为1的Result数据,找不到则返回“404未找到”,Result有密码则返回“401未授权”
Get http://localhost:5001/API/ Result /1?password=123456获取Id为1的加密数据Result数据,如果密码不对则返回“401未授权”
Post http://localhost:5001/API/Result,在FromBody中加入ResultModel格式的数据(即是通过前端),提交数据通过验证之后就会添加Result,若数据验证失败则会返回400错误的请求。
至此,添加Result、查看Result列表及查看Result详情的WebAPI就完成了,它既可以用来开发手机客户端,也可以在其他地方通过调用接口获取对应的数据。
例子:
首先为HomeController 下的Index的action 添加视图(原有视图删除),代码如下
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>Index</title>
- <script src="~/lib/jquery/dist/jquery.min.js"></script>
- <script type="text/javascript">
- //1.get请求
- $(function () {
- $.ajax({
- url: "/api/Result",//前面的/不能少
- type: "Get",//http请求类型为get,即请求服务器中Get方法
- success: function (data) {
- var str = "";
- str += "<table><tr><td>标题</td></tr>";
- //eval(data[i]).title title中第一个t要小写的,要获取的字段首字母都要小
- 写,如上页图所示,返回的json格式的字段名都是首字母小写。
- for (var i = 0; i < data.length; i++) {
- str += "<tr><td>" + data[i].title + "</td></tr>";
- }
- str += "</table>";
- $("#div1").html(str);
- }
- })
- })
- //2.post请求
- $(function () {
- var postdata = { StuName: "老API" ,Title:"WebAPI测试",Discription:"WebAPI测试-post请求",TypeId:1};
- $.ajax({
- type: "post",
- url: "/api/Result",//前面的/不能少
- contentType: 'application/json', //设置请求参数类型为json字符串
- data: JSON.stringify(postdata), //将json对象转换成json字符串发送
- success: function (data, status) {
- alert("添加成功");
- }
- });
- })
- </script>
- </head>
- <body>
- <div>
- <div id="div1"></div>
- </div>
- </body>
在此视图中,也即客户端通过ajax请求去调用webapi接口,然后输出服务器端返回的数据。下面是get请求与post请求的结果,其中post请求被加密。
补充:
HTTP的响应状态码由5段组成:
补充:
contentType字段用于描述数据实体的类型,就是指定客户端要发送的数据类型。
post请求中常见的contentType的值有四种
1.application/x-www-form-urlencoded
最常见的post数据类型,也是表单提交的数据类型,jquery的ajax默认也是这个
2.multipart/form-data
文件上传时要使用的数据类型
3.application/json
json格式的数据类型
4.text/xml
现在这个很少用了,基本没见过
至此,查找、添加的API服务及前端调用测试完毕。
在实际开发中常用:
HTML5+CSS3 负责UI布局、ajax负责数据请求(同时会用angularjs/VUE.JS进行与数据绑定、jquery 负责页面动画效果、webApi 负责服务端数据接口。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。