ASP.NET CORE系列【五】webapi整理以及RESTful风格化
介绍
什么是RESTful? 这里不多做赘述,详情请百度!
哈哈,本来还想巴拉巴拉介绍一些webapi,RESTful的, 还是算了,咱们直接上干货!(原因是懒!哈哈)
使用
以前使用过mvc的人对webapi 应该都很熟悉,先看一段熟悉的代码
大伙发现了什么没?跟以往mvc大多数相同,但有些地方不同 ,我们来一起看看有何区别
1.首先SysUsersController上面有一段代码
[Produces("application/json")] //[Route("api/SysUsers")] [Route("api/[controller]/[action]")] public class SysUsersController : Controller { }
注释的部分先不管,首先我们接收的json格式内容,然后路由是api/[controller]/[action]
这种情况我们只需要正常的ajax请求就能访问到了,
$.ajax({ url:'/api/SysUsers/Login', type: 'POST', contentType: "application/json; charset=utf-8", data: {UserName:'shumin',Password:'123456'}, success: function (data) { if (data.success) { var href = '@Url.Action("Index")?' + new Date().getTime(); window.location.href = href; } else { alert(data.message); } }, error: function () { alert('服务端错误'); } });
我们运行一下, 发现拿不到数据,
这是为什么呢,经过多番尝试,是前台http请求不对,因为我们约定的json传输,所以数据需要序列化
$.ajax({ url:'/api/SysUsers/Login', type: 'POST', contentType: "application/json; charset=utf-8", data: JSON.stringify({UserName:'shumin',Password:'123456'}), success: function (data) { if (data.success) { var href = '@Url.Action("Index")?' + new Date().getTime(); window.location.href = href; } else { alert(data.message); } }, error: function () { alert('服务端错误'); } });
还有一点需要注意的事,ajax默认的
contentType是application/x-www-form-urlencoded
我们需要改成application/json; charset=utf-8
这样就可以拿到数据了
RESTful
推荐一个关于RESTful的介绍文章 http://www.ruanyifeng.com/blog/2014/05/restful_api
用上面那种方法,会导致URL又臭又长,举个例子
网站:/get_user?id=3
RESTFul: GET /user/3 (GET是HTTP类型)
以前的时候我们写http请求,只会用get post两种,
而注册对应的资源是user,api如下:
GET /user/:id # 获取id用户的信息
POST /user # 创建新的用户(注册)
PUT /user/:id # 更新id用户的信息
DELETE /user/:id # 删除id用户(注销)
我们一起来看看RESTFul API有哪些特点:
- 基于“资源”,数据也好、服务也好,在RESTFul设计里一切都是资源。
- 无状态。一次调用一般就会返回结果,不存在类似于“打开连接-访问数据-关闭连接”这种依赖于上一次调用的情况。
- URL中通常不出现动词,只有名词
- URL语义清晰、明确
- 使用HTTP的GET、POST、DELETE、PUT来表示对于资源的增删改查
使用JSON不使用XML
我们接着来看一看RESTFul API的一些最佳实践原则:
- 使用HTTP动词表示增删改查资源, GET:查询,POST:新增,PUT:更新,DELETE:删除
- 返回结果必须使用JSON
- HTTP状态码,在REST中都有特定的意义:200,201,202,204,400,401,403,500。比如401表示用户身份认证失败,403表示你验证身份通过了,但这个资源你不能操作。
这里直接贴出RESTful的api仅供参考
namespace NetCoreAdmin.Controllers { [Produces("application/json")] [Route("api/SysUsers")] public class SysUsersController : Controller { private readonly EFCoreContext _context; public SysUsersController(EFCoreContext context) { _context = context; } // GET: api/SysUsers [HttpGet] public IEnumerable<SysUser> GetSysUsers() { return _context.SysUsers; } // GET: api/SysUsers/5 [HttpGet("{id}")] public async Task<IActionResult> GetSysUser([FromRoute] int id) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var sysUser = await _context.SysUsers.SingleOrDefaultAsync(m => m.Id == id); if (sysUser == null) { return NotFound(); } return Ok(sysUser); } // PUT: api/SysUsers/5 [HttpPut("{id}")] public async Task<IActionResult> PutSysUser([FromRoute] int id, [FromBody] SysUser sysUser) { if (!ModelState.IsValid) { return BadRequest(ModelState); } if (id != sysUser.Id) { return BadRequest(); } _context.Entry(sysUser).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!SysUserExists(id)) { return NotFound(); } else { throw; } } return NoContent(); } // POST: api/SysUsers [HttpPost] public async Task<IActionResult> PostSysUser([FromBody] SysUser sysUser) { if (!ModelState.IsValid) { return BadRequest(ModelState); } _context.SysUsers.Add(sysUser); await _context.SaveChangesAsync(); return CreatedAtAction("GetSysUser", new { id = sysUser.Id }, sysUser); } // DELETE: api/SysUsers/5 [HttpDelete("{id}")] public async Task<IActionResult> DeleteSysUser([FromRoute] int id) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var sysUser = await _context.SysUsers.SingleOrDefaultAsync(m => m.Id == id); if (sysUser == null) { return NotFound(); } _context.SysUsers.Remove(sysUser); await _context.SaveChangesAsync(); return Ok(sysUser); } private bool SysUserExists(int id) { return _context.SysUsers.Any(e => e.Id == id); } } }