概述
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_DataBIMAPI.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) { 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框架步骤的全部内容,希望文章能够帮你解决搭建WebApi框架步骤所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复