第五章 .net core该怎么玩

项目目标部署环境: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里无处不在的依赖注入

相关文章
相关标签/搜索