搭建WebApi架構步驟__WebApi

來源:互聯網
上載者:User

1、 開啟vs-檔案-建立項目-web-Asp.net Web應用程式-確定-Web Api-Mvc Web API-確定
2、 查看項目Controller檔案夾,下面兩個檔案:
HomeController.cs—–開啟該檔案,該檔案繼承的是Controller.(繼承MVC裡的Contrller)
ValuesController.cs—開啟該檔案,該檔案繼承的是ApiController.(是API的Controller,應調整該控制器的繼承,建立一個基類控制器BaseController,繼承ApiContrller).在這個基類控制器BaseController中寫一些通用的方法。

3、 添加介面協助文檔
第一步:Areas-HelpPage-App_Start-HelpPageconfig.cs開啟:第二行注釋去掉,改成:
config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath(“~/App_Data/BIMAPI.XML”)));
第二步:右擊項目-屬性-產生-選中XML文檔檔案(X):App_Data\BIMAPI.XML
第三步:找個一個介面,在介面上面加上注釋,例如:

       /// <summary>        /// Get方法        /// </summary>        /// <returns></returns>        public IEnumerable<string> Get()        {            return new string[] { "value1", "value2" };        }
    運行項目即可看到該介面的注釋。

4、 添加測試功能
第一步:項目右擊—管理Nuget程式包,聯機—Nuget.org下面,尋找WebApiTestClient.安裝。
第二步:在Areas—HelpPage-Views-Help-Api.cshtml.開啟檔案,最下面加上如下代碼(有的版本安裝完自動安裝,有的需要自己手動添加代碼):

@Html.DisplayForModel("TestClientDialogs")@section Scripts {    @Html.DisplayForModel("TestClientReferences")    <link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />}

5、 添加日誌(異常和提供者記錄日誌)
1、 右擊項目-管理NuGet程式包,安裝NLog.
2、 在項目的根目錄下建立Loggers檔案夾

3、 建立三個類檔案
2.1、AbnormalFilterAttribute.cs內容:

using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Linq;using System.Net;using System.Net.Http;using System.Web;using System.Web.Http;using System.Web.Http.Filters;using System.Web.Http.Tracing;namespace BIMAPI.Loggers{    public class AbnormalFilterAttribute: ExceptionFilterAttribute    {        public override void OnException(HttpActionExecutedContext actionExecutedContext)        {            GlobalConfiguration.Configuration.Services.Replace(typeof(ITraceWriter), new AppLog());            var trace = GlobalConfiguration.Configuration.Services.GetTraceWriter();            trace.Error(actionExecutedContext.Request, "Controller : " + actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerType.FullName + Environment.NewLine + "Action : " + actionExecutedContext.ActionContext.ActionDescriptor.ActionName, actionExecutedContext.Exception);            var exceptionType = actionExecutedContext.Exception.GetType();            if (exceptionType==typeof(ValidationException))            {                var resp = new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent(actionExecutedContext.Exception.Message), ReasonPhrase = "ValidationException" };                throw new HttpResponseException(resp);            }            else if (exceptionType==typeof(UnauthorizedAccessException))            {                throw new HttpResponseException(actionExecutedContext.Request.CreateResponse(HttpStatusCode.Unauthorized));            }            else            {                throw new HttpResponseException(actionExecutedContext.Request.CreateResponse(HttpStatusCode.InternalServerError));            }            //base.OnException(actionExecutedContext);        }    }}

2、2AppLog.cs內容

    using System;using System.Collections.Generic;using System.Linq;using System.Net.Http;using System.Web.Http.Tracing;using NLog;using Newtonsoft.Json;using System.Text;namespace BIMAPI.Loggers{    /// <summary>    /// 日誌    /// </summary>    public sealed class AppLog : ITraceWriter    {        //持久串連--日誌監聽       // private static IPersistentConnectionContext connectContext = GlobalHost.ConnectionManager.GetConnectionContext<LogListenerHub>();        //日誌寫入        private static readonly Logger AppLogger = LogManager.GetCurrentClassLogger();        private static readonly Lazy<Dictionary<TraceLevel, Action<string>>> LoggingMap = new Lazy<Dictionary<TraceLevel, Action<string>>>(() => new Dictionary<TraceLevel, Action<string>>        {            {TraceLevel.Info,AppLogger.Info },            {TraceLevel.Debug,AppLogger.Debug },            {TraceLevel.Error,AppLogger.Error },            {TraceLevel.Fatal,AppLogger.Fatal },            {TraceLevel.Warn,AppLogger.Warn }        });        private Dictionary<TraceLevel,Action<string>> Logger        {            get { return LoggingMap.Value; }        }        /// <summary>        /// 跟蹤編寫器介面實現        /// </summary>        /// <param name="request"></param>        /// <param name="category"></param>        /// <param name="level"></param>        /// <param name="traceAction"></param>        public void Trace(HttpRequestMessage request, string category, TraceLevel level, Action<TraceRecord> traceAction)        {            if (level!=TraceLevel.Off)//未禁用日誌跟蹤            {                if (traceAction != null && traceAction.Target != null)                {                    category = category + Environment.NewLine + "Action Parameters : " + JsonConvert.SerializeObject(traceAction.Target);                }                var record = new TraceRecord(request, category, level);                if (traceAction != null)                {                    traceAction(record);                }              //  traceAction?.Invoke(record);                Log(record);            }            //throw new NotImplementedException();        }        /// <summary>        /// 日誌寫入        /// </summary>        /// <param name="record"></param>        private void Log(TraceRecord record)        {            var message = new StringBuilder();            /**************************作業記錄****************************/            if (!string.IsNullOrWhiteSpace(record.Message))            {                message.Append("").Append(record.Message + Environment.NewLine);            }            if (record.Request!=null)            {                if (record.Request.Method!=null)                {                    message.Append("Method : " + record.Request.Method + Environment.NewLine);                }                if (record.Request.RequestUri!=null)                {                    message.Append("").Append("URL : " + record.Request.RequestUri + Environment.NewLine);                }                if (record.Request.Headers!=null&&record.Request.Headers.Contains("Token")&&record.Request.Headers.GetValues("Token")!=null&&record.Request.Headers.GetValues("Token").FirstOrDefault()!=null)                {                    message.Append("").Append("Token : " + record.Request.Headers.GetValues("Token").FirstOrDefault() + Environment.NewLine);                }            }            if (!string.IsNullOrWhiteSpace(record.Category))            {                message.Append("").Append(record.Category);            }            if (!string.IsNullOrWhiteSpace(record.Operator))            {                message.Append(" ").Append(record.Operator).Append(" ").Append(record.Operation);            }            //***************************異常日誌***********************************//            if (record.Exception!=null&&!string.IsNullOrWhiteSpace(record.Exception.GetBaseException().Message))            {                var exceptionType = record.Exception.GetType();                message.Append(Environment.NewLine);                message.Append("").Append("Error : " + record.Exception.GetBaseException().Message + Environment.NewLine);            }            //日誌廣播         //   connectContext.Connection.Broadcast(Convert.ToString(message));            //日誌寫入本地檔案            Logger[record.Level](Convert.ToString(message) + Environment.NewLine);        }    }}

2、3LogFilterAttribute.cs內容

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Http;using System.Web.Http.Controllers;using System.Web.Http.Filters;using System.Web.Http.Tracing;namespace BIMAPI.Loggers{    public class LogFilterAttribute: ActionFilterAttribute    {        public override void OnActionExecuting(HttpActionContext actionContext)        {            GlobalConfiguration.Configuration.Services.Replace(typeof(ITraceWriter), new AppLog());            var trace = GlobalConfiguration.Configuration.Services.GetTraceWriter();            trace.Info(actionContext.Request, "Controller : " + actionContext.ControllerContext.ControllerDescriptor.ControllerType.FullName + Environment.NewLine + "Action : " + actionContext.ActionDescriptor.ActionName, "JSON", actionContext.ActionArguments);            //base.OnActionExecuting(actionContext);        }    }}

4、 在項目的App_Start的WebApiConfig.cs檔案中添加以下代碼:

        //日誌配置            config.Filters.Add(new LogFilterAttribute());     config.Filters.Add(new AbnormalFilterAttribute());

最終介面:

5、 Web.config中節點下配置以下內容:
在上面:

    <configSections>    <!--日誌-->    <section name="nlog" type="NLog.Config.ConfigSectionHandler,NLog" />    </configSections>

在下面日誌配置:

<nlog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">    <targets>        <target name="logfile" xsi:type="File" fileName="${basedir}/App_Log/${date:format=yyyy-MM-dd}-api.log" />        <target name="eventlog" xsi:type="EventLog" layout="${message}" log="Application" source="Api Services" />    </targets>    <rules>        <logger name="*" minlevel="Trace" writeTo="logfile" />        <logger name="*" minlevel="Trace" writeTo="eventlog" />    </rules></nlog>

最終效果圖:

6、 運行後,就會產生如下檔案夾:

6、 WebApi發布(採用Web Deploy發布,即直接發布到遠程伺服器上)

6、1、需要在遠程伺服器上安裝WDeploy,從網上下載WDeploy.exe安裝檔案。
6、2配置http://jingyan.baidu.com/article/642c9d34e614de644a46f783.html
6、3 需要在伺服器的IIS上建應用程式集區,建網站(目錄可以先建個空的)
6.4、右擊項目-發布,如下設定:

4驗證串連,允許。發布即可。
6、5訪問伺服器上發布後的項目,顯示項目.netframework版本不是4.5.需要在微軟官方下載.netframework 4.5安裝。就沒有問題了。

7、 開始寫簡單的介面
7、1.將App_Start下的WebApiConfig.cs。檔案內容:

config.Routes.MapHttpRoute(                name: "DefaultApi",                routeTemplate: "api/{controller}/{id}",                defaults: new { id = RouteParameter.Optional }            );

改為:

   config.Routes.MapHttpRoute(                name: "DefaultApi",                routeTemplate: "api/{controller}/{action}",                defaults: new { id = RouteParameter.Optional }            );

可分別運行下,看下介面地址有什麼不同。改成action後更方便查看介面名(方法名)
8、 可以在Controller下面建控制器了,(可寫三個返回不同類型的介面,比如:string bool datatable)
9、 添加即時監控日誌
第一步:添加引用SignalR程式包,右擊項目—管理NuGet程式包。找到SignalR程式包,安裝。
第二步:右擊項目-添加-類-選擇OWIN Startup類-類名為:Startup.cs
內容代碼如下:

 using System;using System.Threading.Tasks;using Microsoft.Owin;using Owin;using BIMAPI.Hubs;[assembly: OwinStartup(typeof(BIMAPI.Startup))]namespace BIMAPI{    public class Startup    {        public void Configuration(IAppBuilder app)        {            // 有關如何配置應用程式的詳細資料,請訪問 http://go.microsoft.com/fwlink/?LinkID=316888            app.MapSignalR();            app.MapSignalR<LogTracer>("/LogTracer"); // LogTracer為第四步建立的類名。        }    }}

第三步:項目右擊—建立檔案夾Hubs。
第四步:在Hubs檔案夾下,建立類-Web下—SignalR永久串連類(v2)–類名為LogTracer.cs
第五步:在上面提到的AppLog.cs中加上代碼(代碼位置可參照上面的AppLog.cs內容),這樣即時監測日誌就完成了,接下來在介面展示即時日誌內容:
//持久串連–日誌監聽

      private static IPersistentConnectionContext connectContext = GlobalHost.ConnectionManager.GetConnectionContext<LogTracer>();

//日誌廣播

    connectContext.Connection.Broadcast(Convert.ToString(message));
      第六步:即時日誌顯示,在API後面添加即時日誌監聽:

1、 在Views-Shared-_Layout.cshtml檔案中
@Html.ActionLink(“即時日誌監聽”, “Index”, “Log”, new { area = “” }, null) 2、 在Views下建立檔案夾Log.
3、 在Log檔案夾下,右擊-添加-MVC 5 分布頁(Razor)-檔案名稱Index.cshtml
頁面內容如下:

@{    ViewBag.Title = "即時監聽";}<h2>即時監聽</h2><div>    <input type="button" id="_start" value="開始監聽" />    <input type="button" id="_stop" value="停止監聽" />    <input type="button" id="_clear" value="清空記錄" /></div><div>    <ul id="_messageList"></ul></div>@section scripts{<script src="~/Scripts/jquery-1.10.2.min.js"></script><script src="~/Scripts/jquery.signalR-2.2.1.js"></script>    <script>        $(function () {            var startBtn = $('#_start');            var stopBtn = $('#_stop');            var listener = $.connection('/LogTracer');            enable(stopBtn, false);            enable(startBtn, true);            //啟動            startBtn.click(function () {                startConnection();                enable(stopBtn, true);                enable(startBtn, false);            });            //停止            stopBtn.click(function () {                stopConnection();                enable(startBtn, true);                enable(stopBtn, false);                $('#_messageList').append('<li>監聽已停止...</li>');            });            //清空列表            $('#_clear').click(function () {                $('#_messageList').children().remove();            });            //開啟串連            function startConnection() {                stopConnection();                listener.start().fail(function () {                    $('#_messageList').append('<li>監聽啟動失敗!</li>');                }).done(function () {                    $('#_messageList').append('<li>監聽已啟動...</li>');                });                listener.received(function (message) {                    $('#_messageList').append('<li>' + message + '</li>');                });            }            //中斷連線            function stopConnection() {                if(listener!=null){                    listener.stop();                }            };            //按鈕切換            function enable(button,enabled) {

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.