当前位置:   article > 正文

谈谈如何在ASP.NET CORE MVC中创建web api_创建 public void post([frombody] string value)

创建 public void post([frombody] string value)

 

前言

Webapi也是一种服务,是属于服务端的,供客户端调用,类似webservice,但是与mvc请求方式不一样(MVC通过路由 controller/action请求),Webapi通过不同的HTTP请求(get(查询)、put(更新)、post(增加)、delete)来表达不同的动作(CRUD),只关注数据。它非常适合构建移动客户端服务,显示端可以用H5等进行创建。

MVC与Web api的区别与联系

声明:本小结叙述来微软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格式)

初认识.net core web api

创建ASP.NET CORE webapi默认项目:WebAPIDemo.

Controllers文件夹下有一个ValuesController.cs,默认代码如下:

  1. namespace WebAPIDemo.Controllers
  2. {
  3.     [Route("api/[controller]")]
  4.     [ApiController]
  5.     public class ValuesController : ControllerBase
  6. //.Net Core2.0(VS2017)下默认继承自Controller,且上面没有打[ApiController]特性
  7.     {
  8.         // GET api/values
  9.         [HttpGet]
  10.         public ActionResult<IEnumerable<string>> Get()
  11.         {
  12.             return new string[] { "value1", "value2" };
  13.         }
  14.         // GET api/values/5
  15.         [HttpGet("{id}")]
  16.         public ActionResult<string> Get(int id)
  17.         {
  18.             return "value";
  19.         }
  20.         // POST api/values
  21.         [HttpPost]
  22.         public void Post([FromBody] string value)
  23.         {
  24.         }
  25.         // PUT api/values/5
  26.         [HttpPut("{id}")]
  27.         public void Put(int id, [FromBody] string value)
  28.         {
  29.         }
  30.         // DELETE api/values/5
  31.         [HttpDelete("{id}")]
  32.         public void Delete(int id)
  33.         {
  34.         }
  35.     }
  36. }

运行结果:

启动运行结果如上图所示,得到了服务端数据,这说明就使用了webapi服务。请求格式

https://localhost:44323/api/values

是如何定位到Get方法的呢?

https://localhost:44323/是域名 api是固定的格式 values是控制器

是如何定位到Get方法呢?因为通过URL方法访问默认就是Get请求,默认就去请求Get方法或者以Get开头的方法名

那么是如何定位到有参数Get方法呢,如下图请求,则请求到的是到有一个参数的get方法,因为传入一个参数1

在ASP.NET CORE MVC项目中使用Web api

在ASP.NET Core MVC中,WebAPI就是其中一项功能子集,可以直接使用MVC的特性及路由等功能。

说明:以下以一个文件学习成果管理的场景如理解mvc在web api的使用

1.建立相应的ViewModel

  1. public class ResultViewModel
  2. {
  3. public int Id { get; set; }
  4. public string StuName { get; set; }
  5. public string Title { get; set; }
  6. public string Discription { get; set; }
  7. public string Type { get; set; }
  8. public string Attachment { get; set; }
  9. }

2、添加API控制器类ResultAPIController

VS2019/2017创建的时候会默认加上特性路由[Route(“api/[controller]”)],将其中的[controller]改成Result,然后添加对应的操作,分页查看Result,根据id查看指定Result添加Result。逻辑与Controllers文件夹中的ResultController大致相同。

代码如下:

  1. [Route("api/Result")]
  2. [ApiController]
  3. public class ResultAPIController : Controller
  4. //此处默认是继承ControllerBase,继承这个话ViewBag没有用哦
  5. {
  6. //这里注入了两个依赖的服务,具体的功能可以不去管
  7. //一个是管理成果的各种信息,管理一个是类型
  8. private IResultRepository _resultRepository;
  9. private IResultTypeRepository _resultTypeRepository;
  10. public ResultAPIController(IResultRepository resultRepository,
  11. IResultTypeRepository resultTypeRepository)
  12. {
  13. _resultRepository = resultRepository;
  14. _resultTypeRepository = resultTypeRepository;
  15. }
  16. // GET: api/result 查找
  17. [HttpGet]
  18. public IActionResult Get(int pageindex = 1, int pagesize = 5)
  19. {
  20. var results = _resultRepository.PageList(pageindex, pagesize, out int pagecount);
  21. ViewBag.PageCount = pagecount;
  22. ViewBag.PageIndex = pageindex;
  23. var resultList = results.Select(r => new ResultViewModel
  24. {
  25. Id = r.Id,
  26. StuName= string.IsNullOrEmpty(r.Password) ? r.StuName : "",
  27. Title = string.IsNullOrEmpty(r.Password) ? r.Title : "加密内容",
  28. Discription = string.IsNullOrEmpty(r.Password) ? r.Discription : "",
  29. Attachment = string.IsNullOrEmpty(r.Password) ? r.Attachment : "",
  30. Type = r.Type.Name
  31. });
  32. return Ok(resultList);//不能返回View,返回json
  33. }
  34. //Get api/result/5 根据条件查找
  35. //Get api/result/5?password=123
  36. [HttpGet("{id}")]
  37. public async Task<IActionResult> Detail(int id, string password)
  38. {
  39. var result = await _resultRepository.GetByIdAsync(id);
  40. if (result == null)
  41. {
  42. return NotFound();//返回404错误
  43. }
  44. if (!string.IsNullOrEmpty(result.Password) &&
  45. !result.Password.Equals(password))
  46. {
  47. return Unauthorized();//返回401错误,未授权
  48. }
  49. var resultView = new ResultViewModel
  50. {
  51. Id = result.Id,
  52. StuName=result.StuName,
  53. Title = result.Title,
  54. Discription = result.Discription,
  55. Attachment = result.Attachment,
  56. Type = result.Type.Name
  57. };
  58. return Ok(resultView);
  59. }
  60. //POST api/result 增加
  61. //方法参数前加[FromBody] 标识,表示该参数值应该从请求的Body中获取,而不是从URL等其他地方中获取
  62. [HttpPost]
  63. public async Task<IActionResult> Post([FromBody] ResultModel model)
  64. {
  65. await _resultRepository.AddAAsync(new Result
  66. {
  67. StuName = model.StuName,
  68. Title = model.Title,
  69. Discription = model.Discription,
  70. Create = DateTime.Now,
  71. TypeId = model.TypeId,
  72. });
  73. return Content("ok");
  74. }
  75. }

运行程序访问地址http://localhost:5001/API/Result(不一定是5001下同看下图即可获取第一页的Result数据,数据格式为json(有些浏览器提示为下载文件),结果如下图所示。pageindex参数直接加在访问地址后面,如http://localhost:5001/API/Result?pageindex=2这代表访问第二页数据

Get  http://localhost:5001/API/ Result /1获取Id为1Result数据,找不到则返回“404未找到”,Result有密码则返回“401未授权

Get  http://localhost:5001/API/ Result /1?password=123456获取Id为1的加密数据Result数据,如果密码不对则返回“401未授权

Post http://localhost:5001/API/ResultFromBody中加入ResultModel格式的数据(即是通过前端)提交数据通过验证之后就会添加Result,若数据验证失败则会返回400错误的请求

至此添加Result、查看Result列表及查看Result详情的WebAPI就完成了可以用来开发手机客户端也可以在其他地方通过调用接口获取对应的数据。

基于api的前后端数据交互

比如:把HomeController看成是客户端,ResultAPIController(webapi)看成是接口端(服务端),通过客户端去调用webapi接口。

例子:

首先为HomeController 下的Index的action 添加视图(原有视图删除),代码如下

  1. <html>
  2. <head>
  3. <meta name="viewport" content="width=device-width" />
  4. <title>Index</title>
  5. <script src="~/lib/jquery/dist/jquery.min.js"></script>
  6. <script type="text/javascript">
  7. //1.get请求
  8. $(function () {
  9. $.ajax({
  10. url: "/api/Result",//前面的/不能少
  11. type: "Get",//http请求类型为get,即请求服务器中Get方法
  12. success: function (data) {
  13. var str = "";
  14. str += "<table><tr><td>标题</td></tr>";
  15. //eval(data[i]).title title中第一个t要小写的,要获取的字段首字母都要小
  16. 写,如上页图所示,返回的json格式的字段名都是首字母小写。
  17. for (var i = 0; i < data.length; i++) {
  18. str += "<tr><td>" + data[i].title + "</td></tr>";
  19. }
  20. str += "</table>";
  21. $("#div1").html(str);
  22. }
  23. })
  24. })
  25. //2.post请求
  26. $(function () {
  27. var postdata = { StuName: "老API" ,Title:"WebAPI测试",Discription:"WebAPI测试-post请求",TypeId:1};
  28. $.ajax({
  29. type: "post",
  30. url: "/api/Result",//前面的/不能少
  31. contentType: 'application/json', //设置请求参数类型为json字符串
  32. data: JSON.stringify(postdata), //将json对象转换成json字符串发送
  33. success: function (data, status) {
  34. alert("添加成功");
  35. }
  36. });
  37. })
  38. </script>
  39. </head>
  40. <body>
  41. <div>
  42. <div id="div1"></div>
  43. </div>
  44. </body>

在此视图中,也即客户端通过ajax请求去调用webapi接口,然后输出服务器端返回的数据。下面是get请求与post请求的结果,其中post请求被加密。

补充:

HTTP的响应状态码由5段组成: 
 

    • 1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急...
    • 2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
    • 3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
    • 4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
    • 5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等

补充

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 负责服务端数据接口

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/586762
推荐阅读
相关标签
  

闽ICP备14008679号