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) {