Fork me on GitHub

Web API

开篇首先提一下三层架构及微服务(即记录boss首次会议培训)。

三层架构

三层架构从上到下顺序为界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。

1:数据访问层:主要是对非原始数据(数据库或者文本文件等存放数据的形式)的操作层,而不是指原始数据,也就是说,是对数据库的操作,而不是数据,具体为业务逻辑层或表示层提供数据服务。可以理解为对数据库的动作(CRUD),在MVC具体为Controller层。

2:业务逻辑层:主要是针对具体的问题的操作,也可以理解成对数据层的操作,对数据业务逻辑处理,如果说数据层是积木,那逻辑层就是对这些积木的搭建。

3:界面层:主要表示WEB方式,也可以表示成WINFORM方式,WEB方式也可以表现成:aspx,如果逻辑层相当强大和完善,无论表现层如何定义和更改,逻辑层都能完善地提供服务。

微服务架构

微服务将系统分为两层:UI、Web API。与三层架构相比较,UI对应界面层,Web API对应业务逻辑层和数据访问层。这种前后端分离的方式,有利于独立开发和管理。深入理解微服务请参考:微服务架构设计

下面进入本文正题:Web API(这里我们提到Web API特指ASP.NET Web API)。

Web API是网络应用程序接口。包含了广泛的功能,网络应用通过API接口,可以实现存储服务、消息服务、计算服务等能力。。。

通俗理解Web API为处理业务逻辑和数据库动作的接口,用来执行操作,返回数据给前端。本博客例子,我们要展示笑话在页面,就需要前端显示给用户,前端显示当然要有数据,那我们的数据就通过API来提供,API就负责连接数据库,执行动作,返回数据。

那么微服务架构的Web API和常用的MVC有什么区别呢?

首先,MVC既有页面,也有数据、逻辑,而Web API只有数据、逻辑,页面由微服务的UI负责;

其次,命名空间不同,MVC在System.Web.Mvc命名空间下,Web API在ASP.NET System.Web.Http命名空间下,因此model binding/filter/routing等功能有所不同;

再次,Web API 可以根据请求报文来返回的相应数据格式。包括JSON和XML。

再再次,Web API 单独做数据请求和MVC做页面请求可以让Web前端和后台更好的解耦,减少开发难度。

最后,Web API更倾向于基于HTTP协议的服务,直接返回用户的数据请求。MVC是建站的一种框架,倾向于返回用户的页面请求。

尝试建立Web API

1.创建项目

新建Web Application项目

点击“OK”,下一步选择Web API,点击“OK”

然后项目创建成功,Controllers里面有一个ValuesController,是自动生成的一个最简单的Web API Controller。

2.添加数据实体模型

按照数据库字段在模型中添加属性。

namespace WebAPI.Jokes.Models
{
    public class Joke
    {
        public int ID { get; set; }

        public string Content { get; set; }

        public int State { get; set; }

        public string Belong { get; set; }

        public DateTime AddDate { get; set; }
    }
}

3.添加Web API控制器

选择空的Web API Controller

创建完成后我们可以看到这里Controller继承的并不是和MVC相同的Controller,而是ApiController.

4.在controllers文件中新建DBConnect类,用来进行数据库的连接读写操作。

首先在Web.config中添加数据库连接字符串。

<connectionStrings>
<add name="Joke" connectionString="data source=PA181;initial catalog=Joke;persist security info=True;user id=sa;password=****(此处为数据库密码);MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using WebAPI.Jokes.Models;

namespace WebAPI.Jokes.Controllers
{
    public class DB
    {
        protected SqlConnection conn;
        //打开连接
        public bool OpenConnection()
        {
            conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Joke"].ConnectionString);
            try
            {
                bool result = true;
                if (conn.State.ToString() != "Open")
                {
                    conn.Open();
                }
                return result;
            }
            catch (SqlException ex)
            {
                return false;
            }
        }
        //关闭连接
        public bool CloseConnection()
        {
            try
            {
                conn.Close();
                return true;
            }
            catch (SqlException ex)
            {
                return false;
            }
        }
        //显示
        public List<Joke> Select()
        {
            SqlDataReader sdr;
            List<Joke> list = new List<Joke>();
            try
            {
                if (conn.State.ToString() == "Open")
                {
                    SqlCommand cmd = new SqlCommand("Select * from Jokes", conn);
                    sdr = cmd.ExecuteReader();
                    while (sdr.Read())
                    {
                        Joke j = new Joke();
                        System.Diagnostics.Debug.WriteLine("ID:{0}\tcontent:{1}\tbelong:{2}\tstate:{3}\ttime:{4}", sdr["ID"], sdr["Content"], sdr["Belong"], sdr["State"], sdr["AddDate"]);
                        j.ID = Convert.ToInt32(sdr["ID"]);
                        j.Content = sdr["Content"].ToString();
                        j.Belong = sdr["Belong"].ToString();
                        j.State = Convert.ToInt32(sdr["State"]);
                        j.AddDate = Convert.ToDateTime(sdr["AddDate"]);

                        list.Add(j);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Joke details wrong:{0}", e);
            }
            finally
            {
                conn.Close();
            }
            return list;
        }
        //Detail
        public Joke Detail(int? id)
        {
            SqlDataReader sdr;
            Joke j = new Joke();
            System.Diagnostics.Debug.WriteLine("编号:{0}", id);
            string sql = "Select * from Jokes where ID = @ID";
            SqlParameter[] paras = new SqlParameter[]{//参数数组
                  new SqlParameter("@ID",System.Data.SqlDbType.Int)};
            paras[0].Value = id;//绑定ID
            try
            {
                if (conn.State.ToString() == "Open")
                {
                    SqlCommand cmd = new SqlCommand(sql, conn);
                    cmd.Parameters.AddRange(paras);
                    sdr = cmd.ExecuteReader();
                    while (sdr.Read())
                    {

                        System.Diagnostics.Debug.WriteLine("ID:{0}\tcontent:{1}\tbelong:{2}\tstate:{3}\ttime:{4}", sdr["ID"], sdr["Content"], sdr["Belong"], sdr["State"], sdr["AddDate"]);
                        j.ID = Convert.ToInt32(sdr["ID"]);
                        j.Content = sdr["Content"].ToString();
                        j.Belong = sdr["Belong"].ToString();
                        j.State = Convert.ToInt32(sdr["State"]);
                        j.AddDate = Convert.ToDateTime(sdr["AddDate"]);
                    }
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("Joke select wrong:{0}", e);
            }
            finally
            {
                conn.Close();
            }
            return j;

        }
        //Create
        public void Create(Joke joke)
        {
            //SqlDataReader sdr;
            //string sql = "insert into Jokes(Content,Belong,State,AddDate)values('" + joke.Content + "','" + joke.Belong + "','" + joke.State + "','" + joke.AddDate + "')";
            string sql = "insert into Jokes(Content,Belong,State,AddDate)values(@content,@belong,@state,@time)";
            SqlParameter[] paras = new SqlParameter[]{//参数数组
                  new SqlParameter("@content",System.Data.SqlDbType.VarChar),
                   new SqlParameter("@belong",System.Data.SqlDbType.VarChar),
                   new SqlParameter("@state",System.Data.SqlDbType.Int),
                    new SqlParameter("@time",System.Data.SqlDbType.DateTime)};
            paras[0].Value = joke.Content;//绑定内容
            paras[1].Value = joke.Belong;//绑定署名
            paras[2].Value = joke.State;//绑定状态
            paras[3].Value = joke.AddDate;//绑定时间
            try
            {
                if (conn.State.ToString() == "Open")
                {
                    SqlCommand cmd = new SqlCommand(sql, conn);
                    cmd.Parameters.AddRange(paras);
                    cmd.ExecuteNonQuery();
                    System.Diagnostics.Debug.WriteLine("插入成功!");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Joke create wrong:{0}", e);
            }
            finally
            {
                conn.Close();
            }
        }
        //Delete
        public int Delete(int? id)
        {
            string sql = "delete from Jokes where ID= @ID";
            SqlParameter[] paras = new SqlParameter[]{//参数数组
                  new SqlParameter("@ID",System.Data.SqlDbType.Int)};
            paras[0].Value = id;//绑定ID
            int i = 0;
            try
            {
                if (conn.State.ToString() == "Open")
                {
                    SqlCommand cmd = new SqlCommand(sql, conn);
                    cmd.Parameters.AddRange(paras);
                    i = cmd.ExecuteNonQuery();
                    System.Diagnostics.Debug.WriteLine("插入成功!");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Joke create wrong:{0}", e);
            }
            finally
            {
                conn.Close();
            }
            return i;
        }
        //update
        public int Update(Joke joke)
        {
            string sql = "update Jokes set Content = @content,Belong = @belong where ID= @ID";
            SqlParameter[] paras = new SqlParameter[]{//参数数组
                  new SqlParameter("@content",System.Data.SqlDbType.VarChar),
                   new SqlParameter("@belong",System.Data.SqlDbType.VarChar),
                   new SqlParameter("@ID",System.Data.SqlDbType.Int)};
            paras[0].Value = joke.Content;//绑定内容
            paras[1].Value = joke.Belong;//绑定署名
            paras[2].Value = joke.ID;//绑定ID
            System.Diagnostics.Debug.WriteLine("SQL语句:{0}", sql);
            int i = 0;
            try
            {
                if (conn.State.ToString() == "Open")
                {
                    SqlCommand cmd = new SqlCommand(sql, conn);
                    cmd.Parameters.AddRange(paras);
                    i = cmd.ExecuteNonQuery();
                    System.Diagnostics.Debug.WriteLine("更新成功!");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Joke update wrong:{0}", e);
            }
            finally
            {
                conn.Close();
            }
            return i;
        }
    }
}

5.获取数据

新建空的Controller后,我们首先建立一个获取全部数据的方法。

public class JokesController : ApiController
    {
        private DB _db = new DB();
        public List<Joke> GetJokes() {
            _db.OpenConnection();
            return _db.Select();
        }
    }

6.添加View

先打开HomeController,里面添加一个新的Action代码如下,因为我们要在MVC中对于JokeController添加对应的View。

 

public ActionResult Joke() {
            string apiUri = Url.HttpRouteUrl("DefaultApi",new { controller = "Joke"});
            ViewBag.ApiUrl = new Uri(Request.Url, apiUri).AbsoluteUri.ToString();
            return View();
        }

然后右键Joke方法,Add View,选择空模板,Model选择我们建立的实体模型

然后在View中添加访问API的代码:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.3.0.js")"></script>
    <script type="text/javascript">
      
      $(document).ready(function () {
          $.getJSON('/api/jokes')
              .done(function (data) {
                  $.each(data, function (key, item) {
                      $('<li>', { text: formatItem(item) }).appendTo($('#jokes'));
                  });
              });
        })
        function formatItem(item) {
            return item.Content + ',' + item.Belong + ',' + item.AddDate;
        }
        function find() {
            var id = $('#jokeid').val();
            $.getJSON('/api/jokes/' +id)
                .done(function (data) {
                    $('#joke').text(formatItem(data));
                })
                .fail(function (jqXHR,textStatus,err) {
                    $('#joke').text('Error:'+err);
                });
        }
    </script>
}

<div>
    <ul id="jokes"></ul>
</div>
<div>
    <h2>Search by ID</h2>
    <input type="text" id="jokeid" size="5" />
    <input type="button" value="Search" onclick="find();" />
    <p id="joke" />
</div>

然后在_layout.cshtml中添加一个Joke页面的链接

<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home", new { area = "" }, null)</li>
<li>@Html.ActionLink("API", "Index", "Help", new { area = "" }, null)</li>
<li>@Html.ActionLink("Joke", "Joke", "Home", new { area = "" }, null)</li>
</ul>

最后,让我们运行程序看一下结果。

程序运行我们看到自建的首页面:

可以看到顶部有我们在_layout.cshtml中添加的Joke页面的链接Joke,点击Joke,跳转到Joke页面,信息已经显示出来

大功告成!

其它API如Create,Update,Delete,在JokeController中依次添加,View页面使用ajax调用API即可。

 

posted @ 2018-04-13 17:35  Yancy317  阅读(421)  评论(0编辑  收藏  举报