.Net 5框架下的Web API

1.Rest_Full风格:不再是调用方法,把服务资源化(所有东西视为资源)看做一个整体,对外提供URL-统一资源定位器 提供Get/Post/Delete/Update

2. .Net5 默认自带Swageer 注意,statup中间件注册没生效可能会存在顺序关系!

3.cmd命令程序开启web程序 输入命令 dotnet  XXXXX项目名.dll --urls=“http://*:5400” 

4.api 前后端调用例子

.Net 5框架下的Web API
namespace Zhaoxi.AspNetCoreDemo.WebApi.Controllers
{
    /// <summary>
    /// 特性路由
    /// template:中括号代表 变量
    /// 控制器上标的Route模板和Action上标记Route模板内容会链接起来
    /// 如果加上特性路由以后:确定到方法了,以路由定义的名称为准
    /// </summary>
    //[Route("api/[controller]")]
    //[CustomActionFilterAttribute]//整个控制器都支持跨域了;
    [ApiExplorerSettings(GroupName = "V1")]
    [ApiController] //WebApi特有
    public class FirstController : ControllerBase
    {

        [HttpGet]
        [Route("api/[controller]/GetDataTable")]
        public DataTable GetDataTable()
        {
            return null;
        }


        /// <summary>
        /// 这是V1版本的GetString
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/[controller]/GetString")]
        public string GetToString()
        {

            //HttpContext.Response.Headers.Add("Access-Control-Allow-Origin","*");//允许跨域了;
            var reuslt = Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                Id = 123,
                Name = "闪电五连鞭"
            });

            Console.WriteLine(reuslt);

            return reuslt;
        }

        /// <summary>
        /// 这是V1版本的GetString002
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/[controller]/GetString002")]
        public string GetString002()
        {
            //HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");//允许跨域了;
            return Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                Id = 123,
                Name = "闪电五连鞭"
            });
        }

        /// <summary>
        /// 这是V1版本的Add
        /// </summary>
        /// <returns>name</returns>
        [HttpPost]
        [Route("api/[controller]/Add/{name:required}")]
        public string Add(string name)
        {
            //HttpContext.Response.Headers.Add("Access-Control-Allow-Origin","*");//允许跨域了;
            return Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                Id = 234,
                Name = name
            });
        }

        [HttpPut]
        [Route("api/[controller]/Update/{id:int}")]
        public int Update(int Id)
        {
            return Id;
        }
        [Route("api/[controller]/Update/{id:int}")]
        [HttpDelete]
        public int Delete(int Id)
        {
            return Id;
        }

        [Route("api/[controller]/Patch")]
        [HttpPatch]
        public int Patch()
        {
            return 123;
        }

        [Route("api/[controller]/GetUser")]
        [HttpPost]
        public string GetUser(Users user)
        {
            Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(user));
            return Newtonsoft.Json.JsonConvert.SerializeObject(user);
        }


        [Route("api/[controller]/GetStudent")]
        [HttpGet]
        public string GetStudent()
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                id = 234,
                Name = "笑脸",
                Age = 24,
                Description = "奥术大师多"
            });
        }
    }
}
后端接收
.Net 5框架下的Web API
@{
    ViewData["Title"] = "Index";
}

<h1>this is  Client Api</h1>

<form method="post" action="/api/Ninth/register?id=1">
    <div class="row">
        <div class="col-md-5">
            <h2>Test </h2>
            <p>
                <input type="text" id="txtAccount" name="账号" />
                <input type="text" id="txtPassword" name="密码" />
                <input type="button" id="btnLogin" value="登陆" />
            </p>

            <p><input type="text" id="txtId" name="id" /> </p>
            <p>
                <input type="button" id="btnGet1" value="Get1" />
                <input type="button" id="btnGet2" value="Get2" />
                <input type="button" id="btnGet3" value="Get3" />
                <input type="button" id="btnGet4" value="Get4" />
            </p>
            <p>
                <input type="button" id="btnGet5" value="Get5" />
                <input type="button" id="btnGet6" value="Get6" />
                <input type="button" id="btnGet7" value="Get7" />
            </p>

            <p>
                <input type="button" id="btnPost1" value="Post1" />
                <input type="button" id="btnPost2" value="Post2" />
                <input type="button" id="btnPost3" value="Post3" />
                <input type="button" id="btnPost4" value="Post4" />
            </p>
            @*<p><input type="submit" id="btnPost" /> </p>*@
            <p>
                <input type="button" id="btnPut1" value="Put1" />
                <input type="button" id="btnPut2" value="Put2" />
                <input type="button" id="btnPut3" value="Put3" />
                <input type="button" id="btnPut4" value="Put4" />
                @*<input type="button" id="btnPut5" value="Put5" />
            <input type="button" id="btnPut6" value="Put6" />*@
            </p>
            <p>
                <input type="button" id="httpGet" value="后台模拟HttpGet请求" />
                <input type="button" id="httpPost" value="后台模拟HttpPost请求" />
            </p>
            <p>
                <input type="button" id="btnGetCors1" value="跨域Get1" />
            </p>
        </div>

    </div>
    <script src="~/lib/jquery/dist/jquery.min.js"></script> 
    <script>
        $(function () {
            var user = { UserID: "11", UserName: "Richard", UserEmail: "1030499676@qq.com" };
            var info = "this is muti model";

            $("#btnGet1").on("click", function () {
                //$.ajax({ url: "/api/Ninth", type: "get", data: { "userName": "Superman" }, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });//指向接口,参数匹配的,大小写不区分
                $.ajax({
                    //url: "/api/Ninth/GetUserByName?ticket=" + ticket
                    url: "/api/Ninth/GetUserByName", type: "get", data: { "username": "Superman" },
                    //beforeSend: function (XHR) {
                    //    //发送ajax请求之前向http的head里面加入验证信息
                    //    XHR.setRequestHeader(‘Authorization‘, ‘BasicAuth ‘ + ticket);
                    //},
                    success: function (data) {
                        alert(JSON.stringify(data));
                    }, datatype: "json"
                });
            });
            $("#btnGet2").on("click", function () {//单个参数
                $.ajax({ url: "/api/Ninth/GetUserByID", type: "get", data: { "id": $("#txtId").val() }, success: function (data) { alert(JSON.stringify(data)); }, datatype: "json" });
            });
            $("#btnGet3").on("click", function () {//两个参数
                $.ajax({ url: "/api/Ninth/GetUserByNameId", type: "get", data: { "userName": "Superman", "id": $("#txtId").val() }, success: function (data) { alert(JSON.stringify(data)); }, datatype: "json" });
            });
            $("#btnGet4").on("click", function () {//无参数
                $.ajax({ url: "/api/Ninth/Get", type: "get", data: "", success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });
            $("#btnGet5").on("click", function () {//传递实体,序列化后传递
                $.ajax({ url: "/api/Ninth/GetUserByModelSerialize", type: "get", data: { userString: JSON.stringify(user) }, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });

            //只能传递JSON字符串、[frombody] [fromuri] [fromform]---现在不行
            $("#btnGet6").on("click", function () {//传递实体,序列化后传递
                $.ajax({ url: "/api/Ninth/GetUserByModelSerializeWithoutGet", type: "get", data: { userString: JSON.stringify(user) }, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });
            $("#btnGet7").on("click", function () {//传递实体,序列化后传递  405 Method Not Allowed    不带httpget需要用get开头
                $.ajax({ url: "/api/Ninth/NoGetUserByModelSerializeWithoutGet", type: "get", data: { userString: JSON.stringify(user) }, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });


            $("#btnPost1").on("click", function () {//单个值传递,json数据不要key,这样后台才能获取
                $.ajax({ url: "/api/Ninth/RegisterNone", type: "post", data: {}, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });
            $("#btnPost2").on("click", function () {//key-value形式后台拿不到这个参数,但是可以直接访问
                $.ajax({ url: "/api/Ninth/Register", type: "post", data: { "id": $("#txtId").val() }, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });
            $("#btnPost3").on("click", function () {//传递json格式的,后台可以用实体接收
                $.ajax({ url: "/api/Ninth/RegisterUser", type: "post", data: user, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });
            $("#btnPost4").on("click", function () {//传递json序列化后的格式
                $.ajax({ url: "/api/Ninth/RegisterUser", type: "post", data: JSON.stringify(user), success: function (data) { alert(JSON.stringify(data));  }, datatype: "json", contentType: application/json, });
            });

            //也可以还是包装成一个对象

            $("#btnPut1").on("click", function () {//单个值传递,json数据不要key,这样后台才能获取
                $.ajax({ url: "/api/Ninth/RegisterNoKeyPut", type: "put", data: { "": $("#txtId").val() }, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });
            $("#btnPut2").on("click", function () {//key-value形式后台拿不到
                $.ajax({ url: "/api/Ninth/RegisterPut", type: "put", data: { "id": $("#txtId").val() }, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });
            $("#btnPut3").on("click", function () {//传递json格式的,后台可以用实体接收
                $.ajax({ url: "/api/Ninth/RegisterUserPut", type: "put", data: user, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });
            $("#btnPut4").on("click", function () {//传递json序列化后的格式,后台可以用实体接收,需要指定contentType
                $.ajax({ url: "/api/Ninth/RegisterUserPut", type: "put", data: JSON.stringify(user), success: function (data) { alert(JSON.stringify(data));  }, datatype: "json", contentType: application/json, });
            });

            $("#httpGet").on("click", function () { //先请求到后台,然后由后台发送HttpGet请求再请求到第三方WebApi
                $.ajax({ url: "SendHttpGet", type: "get", data: {}, success: function (data) { alert(JSON.stringify(data)); }, datatype: "json", contentType: application/json, });
            });

            $("#httpPost").on("click", function () { //先请求到后台,然后由后台发送HttpPost请求再请求到第三方WebApi
                $.ajax({ url: "SendHttpPost", type: "post", data: {}, success: function (data) { alert(JSON.stringify(data)); }, datatype: "json", contentType: application/json, });
            });

            //$("#btnPut5").on("click", function () {//JObject接收
            //    $.ajax({ url: "/api/Ninth/RegisterObjectPut", type: "put", data: { "User": user, "Info": info }, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            //});
            //$("#btnPut6").on("click", function () {//Dynamic  失败了
            //    $.ajax({ url: "/api/Ninth/RegisterObjectDynamicPut", type: "put", data: { "User": user, "Info": info }, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json", contentType: ‘application/json‘ });
            //});

            //delete一样 type换成delete
            //如果大家还有别的传递和获取 自动绑定好的方式,欢迎分享

            $("#btnLogin").on("click", function () {
                $.ajax({
                    url: "/api/Ninth/Login",
                    type: "GET",
                    data: { "Account": $("#txtAccount").val(), "Password": $("#txtPassword").val() },
                    success: function (data) {
                        var result = JSON.parse(data);
                        if (result.Result) {
                            ticket = result.Ticket;
                            alert(result.Ticket);
                        }
                        else {
                            alert("failed");
                        }
                    }, datatype: "json"
                });
            });

            var ticket = "";//登陆后放在某个html里面,ajax都得带上

            jQuery.support.cors = true;
            var location = "https://localhost:5400/api/first/GetString";
            $("#btnGetCors1").on("click", function () {
                $.ajax({ url: location, type: "get", data: { "id": 1 }, success: function (data) { alert(JSON.stringify(data));  }, datatype: "json" });
            });

        });
    </script>
</form>
前端调用

 5.浏览器跨域,同源策略

正常:正常http请求是通过浏览器发送给服务器 服务器知道请求人的http协议的信息,如:端口,ip

跨域:ajax http请求是直接一个链接请求到服务器,服务器不知道请求人的身份。

如果没有同源策略.存储在服务器的cookie session 谁过来都能读取

.Net 5框架下的Web API

.Net 5框架下的Web API

 

 

 经典的跨域请求错误事例:

.Net 5框架下的Web API

 多种跨域策略之一 

服务器设置全局允许跨域请求 statup.cs.configure():或者使用特性,控制某个控制器允许跨域

.Net 5框架下的Web API

多种跨域策略之一 在statup.cs.ConfigureServices()下面

.Net 5框架下的Web API

 

 多种跨域策略之二, 在statup.cs.Configure()下面

app.UseCors("AllowCors"); //必须要在UseRouting 之后 在 UseAuthorization之前

 

6.请求压缩响应结果

添加程序集:.Net 5框架下的Web API

 

 在statup.cs下添加代码  支持GZip压缩格式,或者同事支持两种

.Net 5框架下的Web API

在statup.cs.Configure()下面

 .Net 5框架下的Web API

浏览器支持的压缩方式

.Net 5框架下的Web API

 

 

 7.鉴权授权

.Net 5框架下的Web API

 

 Token检验流程

.Net 5框架下的Web API

 

 

1.用户访问鉴权中心,鉴权返回用户token 
2.用户带着token 访问api  api得到用于的token 并不去AuthorizetionServer鉴权中心去访问 

验证流程
api要确定的是这个token是否来自于鉴权中心的token?
如果是来自于鉴权中心的token,如何判断token是否失效?

这时候就需要用到加密技术
1. Des 对称可逆加密
2. Rsa 非对称可逆加密
对称可逆加密: 就是一个key,key可以加密,也必须使用这个key才能够解密
鉴权中心:key1
Api方法:key1    鉴权中心和api是同一个key;
token验证流程:
1.用户在鉴权中心登录成功以后,可以使用key1加密;得到一段密文;
2.用户访问Api的时候,Api方就使用ke1去解密:
4.如果解密成功---防止抵赖(密文一定是来自于鉴权中心),
5.就进一步验证token是否过期,
6.如果过期就拦截,如果没有过期就通过

实际开发中,不会使用对称可逆加密,而是非对称可逆加密;
JWT:  一对key,   二者无法相互推导; 私钥、公钥;
私钥-----鉴权中心;作为加密Key
公钥-----Api方法;作为解密key; 
Api方法只要是通过公钥能够解开密文;说明token是来自于鉴权中心

JWT,IdentityServer4
1.独立的鉴权中心,第一次登陆到鉴权中心,鉴权中心通过用户名密码,生成一个Token/令牌;
2.去访问Api的时候,就带着这个令牌;Api方验证令牌是否有效,如果有效就放行,如果无效,拦截;

  

 

.Net 5框架下的Web API

上一篇:Garbage Collection and C#


下一篇:C# 调用 Rust 编写的 dll 之四:string