項目目標部署環境:CentOS 7+html
項目技術點:.netcore2.0 + Autofac +webAPI + NHibernate5.1 + mysql5.6 + nginx前端
開源地址:https://github.com/wmowm/nh.coremysql
不少小夥伴,初識.net core都不知道如何下手,從哪裏開始學習,這讓我想起羣裏常常有小夥伴問,mvc怎麼學習?nginx
我以爲,第一步應該找到一個切入點,這裏先說mvc,咱們分三種狀況來分析git
1.萌新github
我我的以爲,xxx從入門到精通,是不適合去學習的,特別是萌新,這樣蜻蜓點水的看一遍,根本就起不到任何做用web
最好的方法就是用mvc作一些簡單的demo,登陸,註冊,crud.... 這就是切入點ajax
2.從webform轉入mvcsql
直接看mvc的路由,分部頁,藉助網上的一些資料便可,邊作邊查,mvc就很是簡單了json
3.從別的語言轉入asp.net
熟悉asp.net的一些特性便可,mvc的設計模式是共通的
迴歸正題那.net core怎麼玩?
仍是找切入點,這裏我就拿2年asp.net開發經驗爲原型
切入點就是造輪子,先找咱們最熟悉的地方,一步步開始搭建.net core項目
咱們此次的輪子是經過web api 實現CRUD,這裏個人IDE是vs2017,SDK是.net core 21.4, let's go~~~
第一步,建立一個web api,這裏貼出我在使用中遇到的坑
1.RestFul Action共存
在get狀況下,相同路由的Action沒法共存,運行報錯會匹配到多個Action
在post狀況下,相同路由的Action能夠共存,會存在優先級,可是隻會執行一個正則匹配到的Action
2.RestFul 相同路由的Action如何並存,並訪問指定的Action
[Route("list"),HttpPost]
路由以下 api/{controller}/list
3.RestFul 如何設置多參數,
[Route("list"),HttpPost("{a}/{b}/{c}")]
路由以下 api/{controller}/list/1/2/3
4.Post提交多參數,[FromBody] 跨域問題
去註冊中間件,讓webapi支持跨域
5.Post提交多參數,[FromBody] ajax提交類型錯誤
必須設置:contentType: 'application/json; charset=urf-8'
參數必須格式化成json字符串: data: JSON.stringify(data)
6.關於[FromBody]標識的參數不能設置基礎類型,如string...
錯誤說法,能夠設置成string類型
7.爲何Post提交參數必需要標識[FromBody]
[FromBody]表示該參數值應該從請求的Body中獲取,而不是從URL中獲取,URL有長度限制
在不超過長度限制的狀況下,能夠隨意
第二步,實現web api CRUD
[HttpGet] public async Task<JsonResult> Get(int id) { return await Task.Run<JsonResult>(() => { Common.Json json = new Common.Json(); var model = _UsersService.Get(id); json.data = model; return Json(json); }); }
經過id獲取實體對象,這裏很是好理解,咱們直接去看這個返回的json對象
/// <summary> /// 返回的Json模型 /// </summary> public class Json { private int _status = 0; /// <summary> /// 狀態 -1失敗,0成功 /// </summary> public int status { get { return _status; } set { _status = value; } } public string pitchId { get; set; }//要定位的頁面元素id public string msg { get; set; }//消息 public string returnUrl { get; set; }//跳轉的頁面 public object data { get; set; }//數據 public int total { get; set; }//總條數 }
這裏還加一個屬性,顯示響應狀態,例如token驗證不經過,服務端錯誤500,資源未找到404.....
[Route("getlist"),HttpPost] public async Task<JsonResult> GetList([FromBody]Dictionary<string, dynamic> dic) { return await Task.Run<JsonResult>(() => { Json json = new Common.Json(); //自定義參數模板 List<SearchTemplate> st = new List<SearchTemplate>(); //自定義排序模板 List<SortOrder> order = new List<SortOrder>(); //對參數的操做 foreach (var item in dic.Keys) { //根據用戶名模糊查詢 if (item == "user_name") { st.Add(new SearchTemplate() { key = "user_name", value = dic[item], searchType = EnumBase.SearchType.Like }); } //根據用戶名模糊查詢 if (item == "mobile") { st.Add(new SearchTemplate() { key = "mobile", value = dic[item], searchType = EnumBase.SearchType.Like }); } //排序 if (item == "order") { var str = JsonConvert.SerializeObject(dic[item]); order = JsonConvert.DeserializeObject<List<SortOrder>>(str); } //分頁 if (item == "paging") { var str = JsonConvert.SerializeObject(dic[item]); int [] paging = JsonConvert.DeserializeObject<int[]>(str); st.Add(new SearchTemplate() { key = "", value = paging, searchType = Common.EnumBase.SearchType.Paging }); } //後面能夠根據業務拓展查詢條件 } var list = _UsersService.GetList(st, order); var list_count = _UsersService.GetCount(st); json.data = list; json.total = list_count; return Json(json); }); }
前端提交方法
function getlist() { var param = { //"user_name": "admin", "order": [{ "searchType": 1, "value": "id" }], "paging": [1, 10] }; $.ajax({ type: "post", url: path + "/api/user/getlist", data: JSON.stringify(param), async: false, contentType: 'application/json; charset=urf-8', beforeSend: function (xhr) { xhr.setRequestHeader("token", $("#token").html()); }, success: function (data, status) { if (data.status != 0) { alert(data.msg); } else { vm.list = data.data; } } }); }
param 是一個json對象,它由三個部分組成 查詢參數:key/value ,排序數組 ,分頁數組
後臺解析這些參數,我這裏用的是動態解析,這樣就不用每一個model建立一個dto,在NHibernate裏我使用的是查詢器模式,我只須要把解析的參數填充到查詢器便可
這裏我自定義了兩個模板一個用來傳參分頁,一個用來排序
[Serializable] public class SearchTemplate { /// <summary> /// 要查詢的屬性(對應Model裏的屬性) /// </summary> public string key { get; set; } /// <summary> /// 要查詢的屬性的值(對應Model裏的屬性得值) /// </summary> public object value { get; set; } /// <summary> /// 查詢類型(>,=,In.....) /// </summary> public Common.EnumBase.SearchType searchType { get; set; } } [Serializable] public class SortOrder { /// <summary> /// 排序方式(Asc,Desc) /// </summary> public Common.EnumBase.OrderType searchType { get; set; } /// <summary> /// 要排序的屬性(對應Model裏的屬性) /// </summary> public string value { get; set; }
查詢條件是最容易變動的地方,要考慮到後期拓展,用這種方式是很是好的解決方案,這也體現了NHibernate的強大,除了查詢器模式,仍是有HQL,Linq,Lamdba....
後面是添加,修改,刪除,都很是的簡單
[HttpPost] public async Task<JsonResult> Add(Users user) { return await Task.Run<JsonResult>(() => { Json json = new Common.Json(); if (string.IsNullOrEmpty(user.user_name)) { json.msg = "用戶名不能爲空!"; json.status = -1; return Json(json); } var id = _UsersService.Save(user); json.data = id; json.msg = "添加成功!"; return Json(json); }); }
[HttpPut] public async Task<JsonResult> Edit(Users user) { return await Task.Run<JsonResult>(() => { Json json = new Common.Json(); _UsersService.Update(user); json.msg = "修改爲功!"; return Json(json); }); }
[HttpDelete] public async Task<JsonResult> Delete(string ids) { return await Task.Run<JsonResult>(() => { //自定義返回json對象 Json json = new Json(); foreach (var id in ids.Split(new char[] { ',' })) { var m_nt = _UsersService.Get(Convert.ToInt32(id)); m_nt.is_del = 1; _UsersService.Update(m_nt); } json.msg = "成功刪除" + ids.Split(new char[] { ',' }).Length + "條記錄!"; return Json(json); }); }
這樣咱們就實現了簡單的CRUD,這裏存在兩個問題
1.json裏的時間格式
2.跨域
下章咱們將講解.net core裏無處不在的依賴注入