搭建WebApi框架步骤
来源:互联网 发布:hip2p网络摄像机 编辑:程序博客网 时间:2024/06/15 04:00
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文件中
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) { if (enabled) { button.removeAttr("disabled"); } else { button.attr("disabled", "disabled"); } } }); </script>}
注:分布页和布局页的区别是:分布页只是页面的局部展示的内容,基本是元素div中。布局页,则包括html head body标签是一个完整的Html 页面。
运行后界面如下:
10、 添加消息发送Hub
第一步:在Hubs的文件夹下新增类—Web-SignalR集线器类v2—名:MessageHub.cs
第二步:在Controller文件夹的BaseController.cs里加上代码:如下:
public class BaseController<T> : ApiController where T :Hub { #region signalr集成 protected IHubConnectionContext<dynamic> Clients { get; private set; } protected IGroupManager Groups { get; private set; } protected BaseController() { var context = GlobalHost.ConnectionManager.GetHubContext<T>(); Clients = context.Clients; Groups = context.Groups; } #endregion}
第三步:其他有继承BaseController的控制器,修改继承的代码,如下:
public class PlanController : BaseController<MessageHub>
第四步:继承完BaseController后,接口就可以发送消息给客户端了,代码如下:
Clients.All.SendMessage(2, "");//发送给所有设备 Clients.Client("");//发送给指定的连接设备
注:客户端和服务端的用法规则:定义方法名一致,比如服务端叫SendMessage,客户端也得叫SendMessage,服务端方法中的参数只需要输入值,不需要声明类型,客户端的方法需要声明类型。类型要跟服务端传值一致。
11、 生成项目遇到的问题
第一个:整个解决方案都可以生成成功,但是发布BIMAPI接口的时候,一直提示位于Release下的一个dll找不到。(原因是该接口引用这个dll,而不是引用该项目。将该接口在添加引用的时候,选择项目引用即可。因为发布接口的时候,设置项里Configuration里选择Release。在发布项目项目的时候,它去找的引用为Release文件夹下。所以找不到,就无法发布成功。若改为引用项目,不论是debug还是Release都可以找的到)
- 搭建WebApi框架步骤
- 基于.NET Core 框架搭建WebApi项目
- SSH框架搭建步骤
- Hibernate框架搭建步骤
- SSH框架搭建步骤
- Struts2框架搭建步骤
- 搭建spring框架步骤
- SSH框架搭建步骤
- SpringMVC框架搭建步骤
- SSM框架搭建步骤
- mybatis框架搭建步骤:
- 搭建springmvc框架步骤
- Hibernate框架搭建步骤
- Yii框架搭建项目步骤
- springmvc框架的搭建步骤
- SSH框架搭建步骤(笔记)
- RESTful Webservice 框架搭建步骤
- dva.js框架搭建步骤
- linux脚本批处理替换文件内容的方法
- 关于UWP的一些疑惑
- Git中pull对比fetch和merge
- [数据结构] 数组与链表的优缺点和区别
- Layer 图层圆角、边框 、底纹其他常用操作
- 搭建WebApi框架步骤
- 设置SELinux 策略规则 ? 在Kernel Log 中出现"avc: denied" 要如何处理?
- 你不知道你不懂 javascript
- docker 部署简单nginx服务器
- Angular2表单验证
- Maven中央库地址
- 开源蓝牙协议栈
- 11D日期巧算星座
- 自动化设备的软件框架