WebApi接⼝-如何在应⽤中调⽤webapi接⼝
很⾼兴能再次和⼤家分享webapi接⼝的相关⽂章,本篇将要讲解的是如何在应⽤中调⽤webapi接⼝;对于⼤部分做内部管理系统及类似系统的朋友来说很少会去调⽤别⼈的接⼝,因此可能在这⽅⾯存在⼀些困惑,希望本篇分享⽂章内容能给您们带来帮助或者学习,希望⼤家喜欢,也希望各位多多扫码⽀持和点赞谢谢:
» 简单做个webapi(查询+添加)接⼝
» MVC代码中如何调⽤api接⼝
» ajax如何调api接⼝
下⾯⼀步⼀个脚印的来分享:
» 简单做个webapi(查询+添加)接⼝
⾸先,我们需要有⼀个webapi接⼝项⽬,我这⾥以前⾯⽂章的项⽬来构建本篇⽂章的测试⽤例;这⾥新建⼀个 DbData 数据源类,主要⽤来做数据存储和提供查询列表数据及添加数据⽅法,具体代码如:
1public class DbData
2 {
3public static DbData Current
4 {
5get
6 {
7var key = "dbKey";
8var db = CallContext.GetData(key) as DbData;
9if (db == null)
10 {
11 db = new DbData();
12 CallContext.SetData(key, db);
13 }
14return db;
15 }
16 }
17
18
19private static List<MoStudent> students = new List<MoStudent>(){
20new MoStudent{ Id =1 , Name ="⼩1", Sex = true, Birthday= Convert.ToDateTime("1991-05-31")},
21new MoStudent{ Id =2 , Name ="⼩2", Sex = false, Birthday= Convert.ToDateTime("1991-05-31")},
22new MoStudent{ Id =3 , Name ="⼩3", Sex = false, Birthday= Convert.ToDateTime("1991-05-31")},
23new MoStudent{ Id =4 , Name ="⼩4", Sex = true, Birthday= Convert.ToDateTime("1991-05-31")}
24 };
25
26public List<MoStudent> GetAll()
27 {
28return students;
29 }
30
31public bool Save(MoStudent moStudent)
32 {
33 moStudent.Id = students.Max(b => b.Id) + 1;
34 students.Add(moStudent);
35return true;
36 }
37 }
然后,需要在 ValuesController.cs ⽂件中增加调⽤数据源类 DbData ,代码:private DbData db = DbData.Current; 这⾥使⽤了 DbData 类中的Current属性来获取DbData的实例化对象,这⾥和⼤家简单说下这样做的好处在于统⼀管理调⽤类的实例,因为我们创建的某个操作类后,可能会在不同的⽂件或不同业务中调⽤,如果想调⽤其内部⽅法,那么需要⽤到new⼀个对象,如此⼀来多次在使⽤的地⽅都new⼀次感觉很繁琐,⽽且不容已维护;当然这⾥的DbData是简单的测试⽤例,没有⽤到什么⼯⼚,抽象等设计来处理声明这类的实例(⼤家可以忽略哦);
好了,我们再 ValuesController 中分别创建个获取学⽣列表信息的⽅法 GetAllStudents01_2 和添加学⽣信息的⽅法 AddStudent ,然后填写内部代码如:
1private DbData db = DbData.Current;
2
3 [Route("all01_2")]
4 [AcceptVerbs("POST","GET")]
5public HttpResponseMessage GetAllStudents01_2()
6 {
7var students = db.GetAll();
8return Request.CreateResponse(HttpStatusCode.OK, students);
9 }
10
11 [Route("add")]
12 [HttpPost]
13public HttpResponseMessage AddStudent(MoStudent moStudent)
14 {
15var httpStatus = HttpStatusCode.OK;
16if (ModelState.IsValid)
17 {
18var isfalse = db.Save(moStudent);
19 }
20return Request.CreateResponse(httpStatus, moStudent);
21 }
两个⽅法的参数或者返回信息没有做更多的处理,能够⼤家看就⾏,好了创建完api接⼝代码后,我们来测试访问下学⽣列表接⼝,地址如: localhost:1001/s/all01_2,得到的结果图:
返回的是json格式数据,本篇围绕的数据格式都是json,这也是很常⽤的返回数据格式之⼀;
» MVC代码中如何调⽤api接⼝
⾸先,创建⼀个mvc项⽬,创建⽅式可以看这篇⽂章,然后再 HomeController.cs ⽂件中增加Index(学⽣列表)和Add(添加学⽣信息)两个Action⽅法,并且填写代码如:
1public class HomeController : Controller
2 {
3
4public async Task<ActionResult> Index()
5 {
6
7var searchData = new MoStudent();
8//查询条件
9
10var webapiUrl = "localhost:1001/s/all01_2";
11var httpResponseMsg = new HttpResponseMessage();
12
13using (var httpClient = new HttpClient())
14 {
15 httpResponseMsg = await httpClient.PostAsync(webapiUrl, searchData, new System.Net.Http.Formatting.JsonMediaTypeFormatter());
16 }
17var students = httpResponseMsg.Content.ReadAsAsync<List<MoStudent>>().Result;
18
19return View(students);
20 }
21
22 [HttpGet]
23public ActionResult Add()
24 {
25
26return View();
27 }
28
29 [HttpPost]
30public async Task<ActionResult> Add(MoStudent model)
31 {
32if (ModelState.IsValid)
33 {
34var webapiUrl = "localhost:1001/s/add";
35var httpResponseMsg = new HttpResponseMessage();
36
37using (var httpClient = new HttpClient())
38 {
39 httpResponseMsg = await httpClient.PostAsync<MoStudent>(webapiUrl, model, new System.Net.Http.Formatting.JsonMediaTypeFormatter());
40 }
41 model = httpResponseMsg.Content.ReadAsAsync<MoStudent>().Result;
42 }
43
44 ModelState.AddModelError("", model.Id > 0 ? "添加成功" : "添加失败");
45return View(model);
46 }
47 }
这⾥需要讲解⼏个注意的地⽅, HttpClient 类主要⽤来做接⼝请求的,这⾥我通过传递参数给她的扩展 PostAsync ⽅法来请求我们刚才创建的webapi地址 localhost:1001/s/all01_2,这⾥先来简单看下这个⽅法使⽤到的参数说明:
1//
2// 摘要:
3// 使⽤通过给定格式化程序序列化的指定值,以异步操作⽅式发送 POST 请求。
4//
5// 参数:
6// client:
7// ⽤于发出请求的客户端。
8//
9// requestUri:
10// 请求将发送到的 URI。
11//
12// value:
13// 要写⼊到请求的实体正⽂的值。
14//
15// formatter:
16// ⽤于序列化值的格式化程序。
17//
18// 类型参数:
19// T:
20// 要序列化的对象的类型。
21//
22// 返回结果:
23// ⼀个表⽰异步操作的任务对象。
24public static Task<HttpResponseMessage> PostAsync<T>(this HttpClient client, string requestUri, T value, MediaTypeFormatter formatter);
View Code
值得注意的是最后⼀个参数new System.Net.Http.Formatting.JsonMediaTypeFormatter() , JsonMediaTypeFormatter 类是继承
了 MediaTypeFormatter 类并重写了格式化的⼀些⽅法,因为我们创建的api项⽬要求的是json格式的参数和返回,所以这⾥⽤的
是 JsonMediaTypeFormatter 类,还有其他的格式如: XmlMediaTypeFormatter 等这个也在上⼀篇分享⽂章中使⽤到了,各位可以看下做下了解;
PostAsync⽅法是异步的⽅法,所以咋们需要在调⽤的时候使⽤await修饰,有了await⾃然要有她的配套组合async和 Task 因此就有了咋们的public async Task<ActionResult> Index() 这样的代码;好了废话太多了,咋们⼀起来看下试图view中绑定代码和绑定学⽣列表后的查询结果:
1 @model List<Stage.Api.Extend.MoStudent>
2
3 <div class="row">
4 <h3>学⽣信息列表</h3>
5 <hr />
6 <h4>后台请求接⼝</h4>
7 @using (Html.BeginForm())
8 {
9 <button class="btn btn-default" type="submit">查询</button>
10 <a class="btn btn-default" href="/home/add">添加</a>
11 <hr />
12 <table id="tab01"class="table table-hover table-bordered text-center">
13 <thead>
14 <tr>
15 <td>学⽣编号</td>
16 <td>姓名</td>
17 <td>性别</td>
18 <td>出⽣⽇期</td>
19 </tr>
20 </thead>
21 <tbody>
22 @foreach (var item in Model)
23 {
24 <tr>
25 <td>@item.Id</td>
26 <td>@item.Name</td>
27 <td>@(item.Sex ? "男" : "⼥")</td>
28 <td>@item.Birthday.ToString("yyyy.MM.dd")</td>
29 </tr>
30 }
31 </tbody>
32 </table>
33
34 }
View Code
执⾏⽅法这个学⽣列表Action的Index⽅法后,在浏览器的效果如:
看到结果后,咋们的mvc调⽤webapi的例⼦就成功了,下⾯来看下添加功能,添加⽅法⾥⾯的主要调⽤webapi代码和查询学⽣列表⽅法的代码⼏乎⼀样,只是这⾥调⽤api⽅法后返回的结果是单个学⽣对象信息不是集合了,这⾥只贴⼀下Add视图代码供⼤家参考:
1 @model Stage.Api.Extend.MoStudent
2
3 @{
4 ViewBag.Title = "添加 - 学⽣";
5 }
6
7 <h3>添加 - 学⽣</h3>
8
9
10 @using (Html.BeginForm())
11 {
12 @Html.AntiForgeryToken()
13
14 <div class="form-horizontal">
15 <hr />
ajax实例 文件浏览16 @Html.ValidationSummary(true)
17
18 <div class="form-group">
19 @Html.LabelFor(model => model.Name, "姓名", new { @class = "control-label col-md-2" })
20 <div class="col-md-10">
21 @Html.EditorFor(model => model.Name)
22 @Html.ValidationMessageFor(model => model.Name)
23 </div>
24 </div>
25
26 <div class="form-group">
27 @Html.LabelFor(model => model.Sex, "性别", new { @class = "control-label col-md-2" })
28 <div class="col-md-10">
29 @Html.EditorFor(model => model.Sex)
30 @Html.ValidationMessageFor(model => model.Sex)
31 </div>
32 </div>
33
34 <div class="form-group">
35 @Html.LabelFor(model => model.Birthday, "出⽣⽇期", new { @class = "control-label col-md-2" })
36 <div class="col-md-10">
37 @Html.EditorFor(model => model.Birthday)
38 @Html.ValidationMessageFor(model => model.Birthday)
39 </div>
40 </div>
41
42 <div class="form-group">
43 <div class="col-md-offset-2 col-md-10">
44 <input type="submit" value="服务端保存"class="btn btn-default" />
45 <input type="button" id="btnAjaxSave" value="ajax保存"class="btn btn-default" />
46 </div>
47 </div>
48 <div class="form-group">
49 <div id="divResult"class="col-md-offset-2 col-md-10" >
50
51 </div>
52 </div>
53 </div>
54 }
55
56 <div>
57 @Html.ActionLink("返回列表", "Index")
58 </div>
View Code
值得注意的是这种后台请求不同域之间的api接⼝,不会有跨域的限制,除⾮接⼝本⾝有限制外,下⾯要讲解的ajax⽅式就不相同了;
» ajax如何调api接⼝
⾸先,咋们需要明确⼀个东西,ajax调⽤接⼝不能跨域,这个是必须了解的,⽐如⼿机h5的webapp通常都是使⽤ajax来调⽤接⼝获取数据的,⽽且⼤部分需求都是跨域来请求的,因此本⽰例会在下⾯讲解的时候简单提及到常⽤的⼏种处理⽅式,并且使⽤其中⼀种来讲解,希望能给⼤家带来帮助;为了测试跨域访问情况,我们在上⼀节点的试图中增加如下布局代码:
1 <h4>ajax请求接⼝</h4>
2 <button class="btn btn-default" id="btnSearch">查询</button>
3 <a class="btn btn-default" href="/home/add">添加</a>
4 <hr />
5 <table id="tab"class="table table-hover table-bordered text-center">
6 <thead>
7 <tr>
8 <td>学⽣编号</td>
9 <td>姓名</td>
10 <td>性别</td>
11 <td>出⽣⽇期</td>
12 </tr>
13 </thead>
14 <tbody>
15 <tr>
16 <td colspan="4"></td>
17 </tr>
18 </tbody>
19 </table>
View Code
然后,jquery绑定查询按钮事件代码如:
1 <script type="text/javascript">
2
3 $(function () {
4
5 $("#btnSearch").on("click", function () {
6
7var tabObj = $("#tab tbody");
8 tabObj.html('tr><td colspan="4">加载中...</td></tr>');
9
10 $.post("localhost:1001/s/all01_2", {}, function (data) {
11
12var tabHtml = [];
13 $.each(data, function (i, item) {
14
15 tabHtml.push('<tr>');
16 tabHtml.push("<td>" + item.Id + "</td>");
17 tabHtml.push("<td>" + item.Name + "</td>");
18 tabHtml.push("<td>" + (item.Sex ? "男" : "⼥") + "</td>");
19 tabHtml.push("<td>" + item.Birthday + "</td>");
20 tabHtml.push('</tr>');
21 });
22if (tabHtml.length <= 0) { return false; }
23
24 tabObj.html(tabHtml.join(''));
25 });
26 });
27 })
28 </script>
然后,⽤iis新发布⼀个站点指向和上⾯mvc项⽬例⼦⼀样的磁盘⽬录,然后iis路由地址为: localhost:1002/home,注意那我们刚才的webapi 地址为 localhost:1001/s/all01_2,这两个地址区别在于,⼀个是1002端⼝⼀个是1001端⼝,这样就构建好了咋们跨域的要求了(当然有些朋友会
在意在说为什么不配置个host本地域名来测试呢,我只能说这是⼀样的效果),然后我们访问 localhost:1002/home路由,并且点击我们绑定好的查询事件按钮,会有这样⼀个ajax请求输出来的错误:
很显然这是跨域提⽰的错误,我们要怎么避免他呢,市⾯上通常的⽅式
1. 使⽤jsonp格式来处理
2. 在接⼝端写⼊接受跨域请求的设置
很显然咋们本次测试⽤的是第⼆种,⽅便,快速就能完成,不过这⾥因为是webapi,所以这⾥直接使⽤微软提供的Cors的服务,我们需要使⽤nuget控制台录⼊如下指定: Install-Package Microsoft.AspNet.WebApi.Cors -Version 5.0.0,⽬前最后更新的版本是:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论