本文所有的东西都是在dot Net Core 1.1环境+VS2017保证测试通过。
本文接着上次文章接着写的,不了解上篇文章的可能看着有点吃力。我尽量让大家都能看懂。这是上篇文章的连接http://www.cnblogs.com/qulianqing/p/6745409.html。请大家先看一下,心里大致有个了解,然后看这篇博客就容易了。
这里说一下实现的步骤:1. 新建一个ASP dot Net MVC项目,在这里我的项目名为TestAPI
2. 在项目的根目录下添加一个文件夹 名字为Models
3. 在Models文件夹下添加一个Users.cs 类 下面是代码 和上篇博客的Users.cs一样 (主要是为了传输数据方便)
public class Users
{
[Key]
public int ID { get; set; }
public string name { get; set; }
public string pwd { get; set; }
}
Users.cs
4.在右键点击controllers文件夹 选择添加-->控制器 在弹出的对话框中选择 mimial Dependencies 之后等待完成。(这里说一下上篇博客有朋友说
选择 mimial Dependencies会出现错误,我今天又试了一遍,还是没有问题,如果说你的也有问题的话那就选择full Dependencies)
mini)
5.再次右键点击Controllers文件夹 选择添加 ->控制器 在弹出的对话框中选择 第三个,也就是下边高亮的那一个 点击添加按钮
6.点击添加按钮之后,又会出现一个对话框,在对话框中选择点击模型的下拉框,选择Uses.cs 。在数据上下文项点击右边的那个加号,在弹出的对话框中,选将名称更改为Users,最后记得视图的三个选项都要勾选。点击添加 就完成了。
7.删除不必要的东西 (1)删除Views下边的整个Home文件夹里边的东西,(2)删除整个Data文件夹,及内部东西,(3)删除Controllers文 件夹下的HomeController.cs (4) 打开appsettings.json文件夹 ,删除ConnectionStrings项及其内容,
(5)打开Startup.cs文件 删除EF框架自动添加的服务 在ConfigureServices这个方法里边, 这个字符串 services.AddDbContext<UsesContext>options=>options.UseSqlServer(Configuration.GetConnectionString("*****")));
(6)打开Contollers文件夹下的UserController.cs文件,删除下边的系统为我们生成的大部分代码,删除完之后就剩下这些
public class UsersController : Controller
{
// GET: Users
public async Task<IActionResult> Index()
{ }
// GET: Users/Details/5
public async Task<IActionResult> Details(int? id)
{ }
// GET: Users/Create
public IActionResult Create()
{ }
// POST: Users/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,name,pwd")] Users users)
{ }
// GET: Users/Edit/5
public async Task<IActionResult> Edit(int? id)
{ }
// POST: Users/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,name,pwd")] Users users)
{ }
// GET: Users/Delete/5
public async Task<IActionResult> Delete(int? id)
{ } // POST: Users/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{ } }
UsersController.cs
进行到这里我们的基础环境就搭建完毕了,我们这里只用系统为我们生成的View 其他的都不用要,在这里我们的Views文件夹下的Users文件夹的东西我们没有动
二、接下来重点来了
我们要在Controllers调用我们上次写的WebAPI
首先我们依次从index到Create到Update 到Delete依次为大家详解(最后附完整的代码,如果代码阅读能力强的同学,可以直接跳到最后阅读全部的代码)
准备工作,首先我们声明两个全局变量,具体用途在注释中已经说明
//这个baseURL是我的webApi的地址
private static string baseURL = "http://localhost:56853/api/users";
//用于存放所有的用户
private static IList<Users> _context;
构造函数 获取所有的用户信息就是把数据存在 _context 中 方便查找
public UsersController()
{
//实例化对象
_context = new List<Users>();
//获取所有的用户的信息
_context = GetAllUserList(); }
在这里我取数据的使用用的是HttpClient取的远程的API数据,由于取的是JSon字符串数组,我要把它转化为JSon数组,然后再通过JSonConvert进行每一个对象的转化
/// <summary>
/// 获取所有用户的List
/// </summary>
private IList<Users> GetAllUserList()
{
IList<Users> userslist = new List<Users>();
var JsonString = GetALLUserInfoFromAPI();
JArray UsersArray = JArray.Parse(JsonString);
for (int i = ; i < UsersArray.Count; i++)
{
userslist.Add(StringConvertToUser(UsersArray[i].ToString()));
}
return userslist;
}
GetAllUserList
/// <summary>
/// 通过api获取所有的用户的信息
/// </summary>
/// <returns>JSON String</returns>
private string GetALLUserInfoFromAPI()
{
HttpClient client = new HttpClient();
var con = client.GetStringAsync(baseURL);
return con.Result;
}
GetALLUserInfoFromAPI
/// <summary>
/// 将Json对象的字符串转化为users对象
/// </summary>
/// <param name="JsonString">json对象的字符串</param>
/// <returns>Users对象</returns>
private Users StringConvertToUser(string JsonString)
{
return JsonConvert.DeserializeObject<Users>(JsonString);
}
StringConvertToUser
1.index 界面是用来显示数据的。通过上边的操作,我们已经把所有的数据存到 _context 变量中去了,所以在Index中我们只需要调用就可以了。
public async Task<IActionResult> Index()
{
return View(_context);
}
运行结果:
2.接下来我们接着说Create和Rdit和Delete 由于Create和Edit都是向服务器提交数据的,Delete向远程API路由一个ID就结束了。这里我原本准备全文都用HttpClient的可是HttpClient的PostAsync方法实在是不会用,昨天搞了一天都没有结果,于是下边的我换成了WebRequest,我把他们提取到一个方法里了,具体看下边的代码。尤其是我下边注释的行代码,不然浏览器会报415让你摸不着头脑,这个是我自己试出来的,可能会有更好的方法吧。只是我还不知道。
/// <summary>
/// 处理数据
/// </summary>
/// <param name="Data">User实体类</param>
/// <param name="Url">远程API的URL</param>
/// <param name="RequestMethod">请求的方法</param>
/// <returns></returns>
private async Task<string> HandleData(Users Data, string Url, string RequestMethod)
{
string UsersJson = UsersConvertToJson(Data);
var request = WebRequest.CreateHttp(Url);
request.Accept = "application/json";
//下边这行不设置会出现无法识别mediaType 415 这个错误
request.ContentType = "application/json";
request.Method = RequestMethod;
//向request提交数据
using (StreamWriter writer = new StreamWriter(await request.GetRequestStreamAsync()))
{
writer.Write(UsersJson);
}
//获取响应
var reponse = await request.GetResponseAsync();
//返回响应数据
using (StreamReader reader = new StreamReader(reponse.GetResponseStream()))
{
return reader.ReadToEnd();
}
}
private string UsersConvertToJson(Users u)
{
return JsonConvert.SerializeObject(u);
}
UsersConvertToJson
具体用法 Create
/// <summary>
/// 传递数据到远程API的数据库中
/// </summary>
/// <param name="u"></param>
/// <returns></returns>
private async Task<string> CreateAsync(Users u)
{
string url = baseURL;
string requestMethod = "post";
return await HandleData(u, url, requestMethod);
} // GET: Users/Create
public IActionResult Create()
{
return View();
} // POST: Users/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,name,pwd")] Users users)
{
if (ModelState.IsValid)
{ await CreateAsync(users);
return RedirectToAction("Index");
}
return View();
}
Create
具体用法 Edit
private async Task<string> UpdateAsync(Users u)
{
string url = baseURL + @"/" + u.ID;
string requestMethod = "put";
return await HandleData(u, url, requestMethod);
} // GET: Users/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return BadRequest();
}
var users = _context.FirstOrDefault(u => u.ID == id);
if (users == null)
{
return NotFound();
}
return View(users);
} // POST: Users/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,name,pwd")] Users users)
{ if (ModelState.IsValid)
{
if (id != users.ID)
{
return BadRequest();
}
try
{
await UpdateAsync(users);
return RedirectToAction("Index");
}
catch
{
if (UsersExist(users.ID))
{
return NotFound();
}
throw;
} }
return View();
}
Edit
private bool UsersExist(int iD)
{
return _context.Any(u => u.ID == iD);
}
UsersExist
具体用法 Delete
private async Task<string> DeleteAsync(Users u)
{
string url = baseURL + @"/" + u.ID;
string requestMethod = "delete";
return await HandleData(u, url, requestMethod);
} // GET: Users/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return BadRequest();
}
var users = _context.FirstOrDefault(u => u.ID == id);
if (users == null)
{
return NotFound();
} return View(users);
} // POST: Users/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var users = _context.SingleOrDefault(u => u.ID == id);
await DeleteAsync(users);
return RedirectToAction("Index");
}
Delete
到这里调用远程API的东西都完成了,我在这里完善了一下 Details这个View
// GET: Users/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return BadRequest();
}
var users = _context.FirstOrDefault(u => u.ID == id);
if (users == null)
{
return NotFound();
}
return View(users);
}
Details
下边这是测试结果
到这里全部都完成了,并且测试完毕
这是UsersContellers.cs 类的全部代码
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using TestAPI.Models; namespace TestAPI.Controllers
{
public class UsersController : Controller
{
#region 成员变量
//这个baseURL是我的webApi的地址
private static string baseURL = "http://localhost:56853/api/users";
//用于存放所有的用户
private static IList<Users> _context; #endregion #region 构造函数
public UsersController()
{
//实例化对象
_context = new List<Users>();
//获取所有的用户的信息
_context = GetAllUserList(); } #endregion #region 类内方法 /// https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client /// <summary>
/// 通过api获取所有的用户的信息
/// </summary>
/// <returns>JSON String</returns>
private string GetALLUserInfoFromAPI()
{
HttpClient client = new HttpClient();
var con = client.GetStringAsync(baseURL);
return con.Result;
} private string UsersConvertToJson(Users u)
{
return JsonConvert.SerializeObject(u);
}
/// <summary>
/// 传递数据到远程API的数据库中
/// </summary>
/// <param name="u"></param>
/// <returns></returns>
private async Task<string> CreateAsync(Users u)
{
string url = baseURL;
string requestMethod = "post";
return await HandleData(u, url, requestMethod);
} private async Task<string> UpdateAsync(Users u)
{
string url = baseURL + @"/" + u.ID;
string requestMethod = "put";
return await HandleData(u, url, requestMethod);
}
/// <summary>
/// 处理数据
/// </summary>
/// <param name="Data">User实体类</param>
/// <param name="Url">远程API的URL</param>
/// <param name="RequestMethod">请求的方法</param>
/// <returns></returns>
private async Task<string> HandleData(Users Data, string Url, string RequestMethod)
{
string UsersJson = UsersConvertToJson(Data);
var request = WebRequest.CreateHttp(Url);
request.Accept = "application/json";
//下边这行不设置会出现无法识别mediaType 415 这个错误
request.ContentType = "application/json";
request.Method = RequestMethod;
//向request提交数据
using (StreamWriter writer = new StreamWriter(await request.GetRequestStreamAsync()))
{
writer.Write(UsersJson);
}
//获取响应
var reponse = await request.GetResponseAsync();
//返回响应数据
using (StreamReader reader = new StreamReader(reponse.GetResponseStream()))
{
return reader.ReadToEnd();
}
}
private async Task<string> DeleteAsync(Users u)
{
string url = baseURL + @"/" + u.ID;
string requestMethod = "delete";
return await HandleData(u, url, requestMethod);
}
private bool UsersExist(int iD)
{
return _context.Any(u => u.ID == iD);
} /// <summary>
/// 获取所有用户的List
/// </summary>
private IList<Users> GetAllUserList()
{
IList<Users> userslist = new List<Users>();
var JsonString = GetALLUserInfoFromAPI();
JArray UsersArray = JArray.Parse(JsonString);
for (int i = ; i < UsersArray.Count; i++)
{
userslist.Add(StringConvertToUser(UsersArray[i].ToString()));
}
return userslist;
}
/// <summary>
/// 将Json对象的字符串转化为users对象
/// </summary>
/// <param name="JsonString">json对象的字符串</param>
/// <returns>Users对象</returns>
private Users StringConvertToUser(string JsonString)
{
return JsonConvert.DeserializeObject<Users>(JsonString);
}
#endregion #region Index
// GET: Users
public async Task<IActionResult> Index()
{
return View(_context);
} #endregion #region Details // GET: Users/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return BadRequest();
}
var users = _context.FirstOrDefault(u => u.ID == id);
if (users == null)
{
return NotFound();
}
return View(users);
} #endregion #region Create // GET: Users/Create
public IActionResult Create()
{
return View();
} // POST: Users/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,name,pwd")] Users users)
{
if (ModelState.IsValid)
{ await CreateAsync(users);
return RedirectToAction("Index");
}
return View();
} #endregion #region Edit // GET: Users/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return BadRequest();
}
var users = _context.FirstOrDefault(u => u.ID == id);
if (users == null)
{
return NotFound();
}
return View(users);
} // POST: Users/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,name,pwd")] Users users)
{ if (ModelState.IsValid)
{
if (id != users.ID)
{
return BadRequest();
}
try
{
await UpdateAsync(users);
return RedirectToAction("Index");
}
catch
{
if (UsersExist(users.ID))
{
return NotFound();
}
throw;
} }
return View();
} #endregion #region Delete // GET: Users/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return BadRequest();
}
var users = _context.FirstOrDefault(u => u.ID == id);
if (users == null)
{
return NotFound();
} return View(users);
} // POST: Users/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var users = _context.SingleOrDefault(u => u.ID == id);
await DeleteAsync(users);
return RedirectToAction("Index");
}
#endregion }
}
UsersController.cs
这是git地址 https://github.com/1483523635/dotNetCoreAPIDemoTest
关于HttpClient的学习微软官网上有一篇 https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client 这个我看了一下时间是2014年的,昨天还能看今天就看不到了,可能是要更新吧
这是HttpClient的API说明 https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.118).aspx
关于HttpClient的PostAsync方法谁有好的用法,欢迎告诉我,让我学习一下。