题外话:
踩坑之路确实是自己踏入正式编程以来走过的坑,坑多,基本过了的都踩了遍,没办法,太菜。
踩坑之路不出意外,应该都是用VS2019和MSSQL做的,没办法,太菜。
不过这个demo我先使用的MVC做的,后来换成了静态页面,改成了WebApi,不该冲动的。。导致后台的Filter配置直接废了- -。换成了API的。
好了扯远了,进入正题。第一次使用博客园,不太会用,尴尬。
首先呢,为了速度,选择用的静态页面。
为什么使用静态页面,基于速度...
详情可以研究下静态页面和动态页面的区别,虽然我也是一时冲动,想纯粹的前后端分离。
一.LayUI
选择LayUI是方便上手,也是第一次学,本来是用BootStrap做的,然后坑就来了。
不过官方说的“低门槛开箱即用的前端 UI 解决方案”确实香。
这里就不多做介绍了。
1.下载包
官方地址就有下载,官方文档也很全,这里不多介绍,下面用到的地方会有详细代码展示。
2.引入
我采用的是模块方式加载,而LayUI的模块加载确实好用。
./layui/css/layui.css
./layui/layui.js
只需两个就好了。
接下来是第一个坑。我们自己做需求时可能会需要自己的封装JS代码,那么就涉及到扩展LauUI模块问题,所以重点来了,如何扩展。
(1)新建文件夹extention
文件夹下新建JavaScript文件,命名import.js。
layui.use('layer', function () {
layui.config({
//存放拓展模块的根目录 (大坑,没认真看文档的下场就是按头深思)
base: '/lib/extention/'
}).extend({
//设定模块别名
Luoextention: 'Luoextention'
});
});
(2) 自己的扩展JS,我这是Luoextention.js.
layui.define()方法。通过这个方法可以把自己需要的依赖模块通过数组格式加载进来。
layui.define(['jquery', 'form', 'layer'], function (exports) {
var layer = layui.layer
, form = layui.form
, $ = layui.jquery
//这里暂且只需要这些
};
exports('Luoextention', Luoextention); //模块名必须和use时使用的模块名一致
});
接下来就是写上自己需要的JS,我这里写上一个扩展的Ajax方法。
layui.define(['jquery', 'form', 'layer'], function (exports) {
var layer = layui.layer
, form = layui.form
, $ = layui.jquery,//看见这个,了吗,这个坑,我就不止按头深思了,而是差点怀疑人生了。没有逗号,自一定的扩展方法会一直提示找不到!!!
Luoextention = { //这个就是你要调用的时使用的名字
ajax: function (url, method, param, fun) {
$.ajax({
url: url,
type: method,
data: param,
beforeSend: function (XHR) {
XHR.setRequestHeader('Authorization', 'BasicAuth ' + sessionStorage.getItem("ticket"));
},
success: function (res) {
fun(res)
}, datatype: "json"
});
}
};
};
exports('Luoextention', Luoextention);
});
我们扩展Ajax中的brforeSend方法,为了做FormsAuthenticationTicket身份验证。通过Ajax在请求头中加入我们的票据信息,从而去判断Request Headers中有无'Authorization',进而可以去设置Api的权限,后面会有API的权限设置讲解。这样就不需要每次使用ajax时,都扩展方法,从而避免重复代码。
因为是静态页面和WebApi的结合,如果需要一个像后台Session的东西去进行存储一些重要数据,那么可以通过FormsAuthenticationTicket将用户的身份发回到客户端的Cookie,去进行权限设置及判断。而Jquery自带的浏览器存储方法,所以我这里使用的是sessionStorage,Key/value的方式去存储后台发送的ticket数据,使用格式sessionStorage.ticket = data;
那么调用时 ,使用layui.use()方法。
使用时导入刚扩展的js文件,切记,引入这个之前一定要导入一个Jquery包,不要问我为什么。
<!--导入文件-->
<script src="/lib/extention/import.js"></script>
<script>
layui.use(['form', 'element', 'Lextention'], function () {
var form = layui.form,
element = layui.element,
Luoextention = layui.Luoextention;
//模块化加载之后,使用同理
Luoextention.ajax("api地址","post/get", {}, fun);
});
</script>
基于此,LayUI 我觉得入门最重要的部分讲完了,之后会涉及到页面弹出层以及表格加载和模块引擎。
那么,就开始前台页面编写。
(3)登入
新建文件夹Static,文件夹下新建Login.html,Index.html。
界面太丑我就不展示了,放主要代码。
LayUI提供自己的表单方法。
前端代码:
<button class="layui-btn layui-btn-fluid" lay-submit="" lay-filter="login">登 入</button> //lay-submit,lay-filter属性很重要很重要...一定要有
layui.use(['form', 'layer','Luoextention'], function () {
var form = layui.form,
layer = layui.layer,
Luoextention = layui.Luoextention;
// 进行登录操作
form.on('submit(login)', function (data) { //
var data = data.field; //layUI内部方法,取到的是name属性值
//还是这样好
//var account = $("#account").val() ,var account = $("#account") ,看有什么区别吗?
//是的,我写快了,找这个BUG找了快一个小时,差点放弃LayUI****,因为会一直提示,提示什么来着我给忘了,反正不会告诉你这个东西
if (data.Role == '') {
layer.msg('请选择身份');
return false;
}
var fun = function(res){
if(res == 200){
layer.msg("登录成功",function(data){
sessionStorage.ticket = data.ticket;
location.href = "Index.html";
});
}
Luoextention.ajax('/api/User/Login','post',data,fun);
}
});
这样前台就写完了,其实我习惯是先写API的。
后台代码 :
WebApi配上Post方法真是太爽了,不过坑我也踩完了。
关于Post提交方法,这里我总结了两种:
第一种:单个参数
后台API控制器上接收一定要用[FromBody]
例如:
Q:
$.ajax({
url:"/api/A",
dataType:"json",
data:{heihei:"sssb"},
success:function(data){
alert(data);
}
})
H:
[HttpPost]
public string A([FromBpdy] string heihei){
return heihei;
}
然后你就会发现,始终得不到SB两字,不对,sssb,[HttpPost]也写了,[FromBody]也写了,为什么呢?修改一下:
$.ajax({
url:"/api/A",
dataType:"json",
data:{" ":"sssb"},
success:function(data){
alert(data);
}
});
这样就会发现弹出了并且得到了梦寐以求的sssb.
第二种:多个参数(两个或两个以上)
将上述.ajax方法改动一个地方,data:{" ":"哈哈哈哈", " ":"嘻嘻嘻嘻"}; 接收改为public string A([FromBody] string heihei,[FromBody] haha){ },
我确实举一反三,所以F12调试得到的永远是:Status Code: 500 Internal Server Error.很不错,还行吧,夸下自己。
错了就改:
前台:
$.ajax({
url:"/api/A",
dataType:"json",
data:{heihei:"嘿嘿嘿嘿",haha:"嘻嘻嘻嘻"},
success:function(data){
alert(data);
}
});
后台:
public class modelB{
public string heihei{ get; set; }
public string haha{ get; set; }
}
[HttpPost]
public string A(modelB model) {
return string.Format("{0},{1}",model.heihei,model.haha);
}
一运行,完美。
所以建议是写一个公共的Model类去处理Post请求。
当然,还有一种是JObject类型接受或者dynamic,不过要记得json序列化。
而JObject要引用Newtonsoft.Json.Linq.会涉及到dll的版本冲突问题,至今这坑没解决,往下适配无效。
接下来剩的就是后台WebApi的代码了,因为涉及到AuthorizeAttribute,比较麻烦。
下次写,要回家做饭了,饿了。