目录
1、创建API
环境说明:
IDE:VS2019社区版;
操作系统:Win 10 专业版
通过VS可方便的创建WebAPI。创建后,会默认创建ValuesController。新建一个API的Controller,并对里面的方法进行了细微修改。具体代码如下:
public class MyAPIController : ApiController
{
// GET: api/MyAPI
public List<Student> Get()
{
List<Student> resultList = new List<Student>();
Student s1= new Student() { sid = "01", sname = "张三" };
Student s2 = new Student() { sid = "02", sname = "李四" };
resultList.Add(s1);
resultList.Add(s2);
return resultList;
}
// GET: api/MyAPI/5
public string Get(int id)
{
return "当前传入的ID值为:"+id;
}
// POST: api/MyAPI
[HttpPost]
public Student Post([FromBody] Student Student)
{
return Student;
}
// PUT: api/MyAPI/5
[HttpPost]
public string Put([FromBody]string value)
{
return "您传入的值为:"+value;
}
// DELETE: api/MyAPI/5
public void Delete(int id)
{
}
}
2、访问API
将代码编译后部署到IIS上,就可以在本地进行访问了。
需要说明一点,在App_Start的WebApiConfig.cs文件中,一开始生成的配置文件内容如下:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}", //这里没有action
defaults: new { id = RouteParameter.Optional }
);
以上的配置没有关联action
,所以即使你的APIController中定义了多个,你能访问的只能是一个(通过浏览器方式)。若通过代码访问(C#发起http请求),则会报如下的错误:
{“Message”:“出现错误。”,“ExceptionMessage”:"找到了与该请求匹配的多个操作:
因此,需要将action
添加待配置文件中。即配置文件如下:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
2.1 通过Get访问
2.1.1 通过浏览器访问
可直接访问链接
http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/Get
得到接口的内容
2.1.2 通过C#发起Http请求(get)
C#发起的Http请求方法如下:
static string getResponseByHttpGet(string Url, string postDataStr)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
return retString;
}
通过调用相关方法,获取对应结果
static void Main(string[] args)
{
string myurl = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/Get";
string postData = "id=12";
string myResponse = getResponseByHttpGet(myurl, postData);
Console.WriteLine(myResponse);
Console.ReadLine();
}
运行后,结果如下
2.2 通过Post访问
1、方法添加HttpPost
属性
public class MyAPIController : ApiController
{
//只对Post方法进行了修改
[HttpPost]
public Student Post([FromBody] Student Student)
{
return Student;
}
}
//新添加了一个类,用于传输数据绑定
public class Student
{
public string sid { get; set; }
public string sname { get; set; }
}
2、C#发起Post请求的方法
//通过键值对方式发送数据
static string getResponseByHttpPostByKeyValue(string url, string postData)
{
//定义request并设置request的路径
WebRequest request = WebRequest.Create(url);
//定义请求的方式
request.Method = "POST";
//设置参数的编码格式,解决中文乱码
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
//设置request的MIME类型及内容长度
request.ContentType = "application/x-www-form-urlencoded"; //配合传入参数,将request的content-type设为form
request.ContentLength = byteArray.Length;
//打开request字符流
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
HttpWebResponse response;
try
{
//定义response为前面的request响应
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
//用于获取明细的异常信息
response = (HttpWebResponse)ex.Response;
}
//获取相应的状态代码
Console.WriteLine(response.StatusDescription);
//定义response字符流
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();//读取所有
//关闭资源
reader.Close();
dataStream.Close();
response.Close();
return responseFromServer;
}
3、通过控制台发起一个POST方式的HTTP请求。
static void Main(string[] args)
{
//Post请求
string postURL = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/POST";
string postData = "sid=12&sname=张三";
string postResponseStr = getResponseByHttpPostByKeyValue(postURL, postData);
Console.WriteLine(postResponseStr);
Console.ReadLine();
}
4、运行效果如下
3、其他处理
3.1 FromBody参数说明
3.1.1 POST方式的数据格式
1、POST
方式Request
请求时需要指定,传递的数据格式,是JSON还是普通的键值对。若为JSON
,则C#发起请求的时候,需要指定request
的content-type
为application/json; charset=utf-8
,并设定编码方式;当为普通键值对时,content-type需要设为application/x-www-form-urlencoded
。两种方式的发起请求,也略微不同。
1.1 当为JSON时,C#发起的请求,应为:
//POST -json格式的请求
string jsonPostURL = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/POST";
Student detailData = new Student() { sid = "001", sname = "张三" }; //将数据转为json
string jsonPostData = JsonConvert.SerializeObject(detailData);
string jsonPostResponseStr = getResponseByHttpPostByJson(jsonPostURL, jsonPostData);
Console.WriteLine(jsonPostResponseStr);
Console.ReadLine();
1.2 当为普通键值对
string postURL = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/POST";
string postData = "sid=12&sname=张三";
string postResponseStr = getResponseByHttpPostByKeyValue(postURL, postData);
Console.WriteLine(postResponseStr);
Console.ReadLine();
3.1.2 FromBody参数
webapi中参数中数据的来源有两种:FromBody和FromUri。在实际的使用中,常常遇到,在使用FromBody,且参数为单一的string时,无法获取传入数据。主要原因是数据格式不准确。
3.1.2.1 单一参数、json格式时
参数应这样调用:
string jsonPostURL = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/put";
string jsonPostData = "'hello'"; //要加上单引号
string jsonPostResponseStr = getResponseByHttpPostByJson(jsonPostURL, jsonPostData);
Console.WriteLine(jsonPostResponseStr);
Console.ReadLine();
这个问题,实际上是如何将一个string表示为json对象。
3.1.2.2 单一参数、key-value格式时
参数的调用方式如下。
string postURL = @"http://localhost/Tsinghua.His.DrugInfoAPI/api/MyAPI/put";
string postData = "=hello"; //参数要这样写
string postResponseStr = getResponseByHttpPostByKeyValue(postURL, postData);
Console.WriteLine(postResponseStr);
Console.ReadLine();
3.2 返回格式为json
1、有时我们想提供的接口,其返回结果都是json。可以将webapi格式器中xml删除即可实现。即在APP_Start
中的WebApiConfig.cs
中加添如下的代码即可:
//清除所有的格式器,然后只添加json格式器
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
两者的返回如图所示
json返回
xml格式返回
2、说明
上面的方案好处是简单、省事,缺点是底层的内容协商仍然在使用,为了能够彻底自定义,可以实现IContentNegotiator
接口,并在config中进行替换。
自定义实现如下:
public class JsonContentNegotiator : IContentNegotiator
{
private readonly JsonMediaTypeFormatter _jsonFormatter;
public JsonContentNegotiator(JsonMediaTypeFormatter formatter)
{
_jsonFormatter = formatter;
}
public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
{
var result = new ContentNegotiationResult(_jsonFormatter, new MediaTypeHeaderValue("application/json"));
return result;
}
}
在Webapiconfig.cs文件中进行替换
var jsonFormatter = new JsonMediaTypeFormatter();
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));
这样,也可以实现返回结果为json。
3.3 POST参数数据
后台接收数据时,可以直接使用Newtonsoft.Json
中的JObject
,这样就不用写个参数对照类。
//输入用户名和密码,判断数据是否可行
[HttpPost]
public string checkUserInfo(JObject jsonObj)
{
ResultModel resultModel = new ResultModel();
try
{
bool checkFlag = LoginService.checkLoginfo(jsonObj["username"].ToString(), jsonObj["password"].ToString());
if (checkFlag)
{
resultModel.MsgCode = "ok";
resultModel.Msg = "验证成功!";
}
else
{
resultModel.MsgCode = "fail";
resultModel.Msg = "验证失败!";
}
}
catch (Exception e)
{
resultModel.MsgCode = "error";
resultModel.Msg = "发生异常!信息如下:"+e.Message;
}
return JsonConvert.SerializeObject(resultModel); ;
}
这篇文章不错,后台接收POST数据的文章
4、代码下载
提取码:NHZL