自WCF之后,现在主流的就是WebAPI,如果你还在用WCF来创建新的项目,那就看看WebAPI是否更好呢!
第一步
新建项目:Ohye.Film.API
添加控制器:FilmController
using Ohye.Film.Application.Film;
using Ohye.Film.DTO.Film;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;namespace Ohye.Film.API.Controllers
{public class FilmController : ApiController{ProductService _productService;public FilmController(ProductService productService){_productService = productService;}/// <summary>/// 获取电影/// </summary>/// <returns></returns>public List<FM_ProductDTO> GetProductList(string name){int total = 0;var result = _productService.Query(1, 25, out total, false, "").ToList();return result;}}
}
添加接口调用监控:
WebApiMonitorLog
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;namespace Ohye.Film.API.Models
{/// <summary>/// 监控日志对象/// </summary>public class WebApiMonitorLog{public string ControllerName{get;set;}public string ActionName{get;set;}public DateTime ExecuteStartTime{get;set;}public DateTime ExecuteEndTime{get;set;}/// <summary>/// 请求的Action 参数/// </summary>public Dictionary<string, object> ActionParams{get;set;}/// <summary>/// Http请求头/// </summary>public string HttpRequestHeaders{get;set;}/// <summary>/// 请求方式/// </summary>public string HttpMethod{get;set;}/// <summary>/// 请求的IP地址/// </summary>public string IP{get { return GetIP(); }}/// <summary>/// 获取监控指标日志/// </summary>/// <param name="mtype"></param>/// <returns></returns>public string GetLoginfo(){string Msg = @"Action执行时间监控:ControllerName:{0}ControllerActionName:{1}开始时间:{2}结束时间:{3}总 时 间:{4}秒Action参数:{5}Http请求头:{6}客户端IP:{7},HttpMethod:{8}";return string.Format(Msg,ControllerName,ActionName,ExecuteStartTime,ExecuteEndTime,(ExecuteEndTime - ExecuteStartTime).TotalSeconds,GetCollections(ActionParams),"",IP,HttpMethod);}/// <summary>/// 获取Action 参数/// </summary>/// <param name="Collections"></param>/// <returns></returns>public string GetCollections(Dictionary<string, object> Collections){string Parameters = string.Empty;if (Collections == null || Collections.Count == 0){return Parameters;}foreach (string key in Collections.Keys){Parameters += string.Format("{0}={1}&", key, Collections[key]);}if (!string.IsNullOrWhiteSpace(Parameters) && Parameters.EndsWith("&")){Parameters = Parameters.Substring(0, Parameters.Length - 1);}return Parameters;}/// <summary>/// 获取IP/// </summary>/// <returns></returns>public string GetIP(){string ip = string.Empty;if (!string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"]))ip = Convert.ToString(System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]);if (string.IsNullOrEmpty(ip))ip = Convert.ToString(System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]);return ip;}}
}
WebApiTrackerAttribute
using Ohye.Film.Infrastructure;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;namespace Ohye.Film.API.Models
{[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]public class WebApiTrackerAttribute : ActionFilterAttribute{private readonly string Key = "_thisWebApiOnActionMonitorLog_";public override void OnActionExecuting(HttpActionContext actionContext){base.OnActionExecuting(actionContext);WebApiMonitorLog MonLog = new WebApiMonitorLog();MonLog.ExecuteStartTime = DateTime.Now;//获取Action 参数MonLog.ActionParams = actionContext.ActionArguments;MonLog.HttpRequestHeaders = actionContext.Request.Headers.ToString();MonLog.HttpMethod = actionContext.Request.Method.Method;actionContext.Request.Properties[Key] = MonLog;var form = System.Web.HttpContext.Current.Request.Form;#region 如果参数是实体对象,获取序列化后的数据Stream stream = actionContext.Request.Content.ReadAsStreamAsync().Result;Encoding encoding = Encoding.UTF8;stream.Position = 0;string responseData = "";using (StreamReader reader = new StreamReader(stream, encoding)){responseData = reader.ReadToEnd().ToString();}if (!string.IsNullOrWhiteSpace(responseData) && !MonLog.ActionParams.ContainsKey("__EntityParamsList__")){MonLog.ActionParams["__EntityParamsList__"] = responseData;}#endregion}public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext){WebApiMonitorLog MonLog = actionExecutedContext.Request.Properties[Key] as WebApiMonitorLog;MonLog.ExecuteEndTime = DateTime.Now;MonLog.ActionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;MonLog.ControllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName;string info = MonLog.GetLoginfo();APILogger.Info($"{ MonLog.ControllerName}.{MonLog.ActionName}", info);if (actionExecutedContext.Exception != null){string requestMessage = string.Format(@"请求【{0}Controller】的【{1}】产生异常:Action参数:{2}Http请求头:{3}客户端IP:{4},HttpMethod:{5}", MonLog.ControllerName, MonLog.ActionName, MonLog.GetCollections(MonLog.ActionParams), MonLog.HttpRequestHeaders, MonLog.GetIP(), MonLog.HttpMethod);string errorMsg = requestMessage + "\r\n" + actionExecutedContext.Exception;APILogger.Info($"{ MonLog.ControllerName}.{MonLog.ActionName}", errorMsg);}}}
}
修改路由规则:
WebApiConfig
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;namespace Ohye.Film.API
{public static class WebApiConfig{public static void Register(HttpConfiguration config){// Web API 配置和服务// Web API 路由config.MapHttpAttributeRoutes();config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{action}/{id}",defaults: new { id = RouteParameter.Optional });}}
}
配置IOC依赖注入
using Autofac;
using OA.Common.DtoModel;
using Ohye.Film.API.Models;
using Ohye.Film.Domain;
using Ohye.Film.Infrastructure;
using Ohye.Film.Infrastructure.EFRepositories;
using Ohye.Film.Infrastructure.EFRepositories.UnitOfWork;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Autofac.Integration.WebApi;
using Ohye.Film.Application;
using Newtonsoft.Json;
using Ohye.Film.Application.Film;namespace Ohye.Film.API
{public class WebApiApplication : System.Web.HttpApplication{protected void Application_Start(){var configuration = GlobalConfiguration.Configuration;configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;var builder = IocCenter.ContainerBuilder; builder.Register<OAUser>(c => CreateOAUser()).AsSelf().InstancePerRequest();SetupResolveRules(builder);builder.RegisterApiControllers(Assembly.GetExecutingAssembly());var container = IocCenter.Container;var resolver = new AutofacWebApiDependencyResolver(container);configuration.DependencyResolver = resolver;AreaRegistration.RegisterAllAreas();GlobalConfiguration.Configure(WebApiConfig.Register);configuration.Filters.Add(new WebApiTrackerAttribute());FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);AutoMapperConfig.RegisterMappings();}protected void SetupResolveRules(ContainerBuilder builder){var application = Assembly.Load("Ohye.Film.Application");builder.RegisterType<EntityManager>().AsSelf().SingleInstance();builder.RegisterAssemblyTypes(application).Where(t => t.Name.EndsWith("Service")).AsSelf();var domainServices = Assembly.Load("Ohye.Film.Domain.Services");builder.RegisterAssemblyTypes(domainServices).Where(t => t.Name.EndsWith("Service")).AsSelf();builder.RegisterType<OhyeFilmDbContext>().InstancePerRequest();builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerDependency();}private OAUser CreateOAUser(){return new OAUser { };}}
}
var resolver = new AutofacWebApiDependencyResolver(container);configuration.DependencyResolver = resolver;AreaRegistration.RegisterAllAreas();GlobalConfiguration.Configure(WebApiConfig.Register);configuration.Filters.Add(new WebApiTrackerAttribute());FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);AutoMapperConfig.RegisterMappings();}protected void SetupResolveRules(ContainerBuilder builder){var application = Assembly.Load("Ohye.Film.Application");builder.RegisterType<EntityManager>().AsSelf().SingleInstance();builder.RegisterAssemblyTypes(application).Where(t => t.Name.EndsWith("Service")).AsSelf();var domainServices = Assembly.Load("Ohye.Film.Domain.Services");builder.RegisterAssemblyTypes(domainServices).Where(t => t.Name.EndsWith("Service")).AsSelf();builder.RegisterType<OhyeFilmDbContext>().InstancePerRequest();builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerDependency();}private OAUser CreateOAUser(){return new OAUser { };}}
}
第二步
启动项目,浏览器中输入:http://localhost:801/Help
使用PostMan调用一下:
第三步
使用API代理调用,新建项目Ohye.Film.ApiClient
Nuget安装:WebApiProxy.CSharp
配置文件:
WebApiProxy.config
<?xml version="1.0" encoding="utf-8" ?>
<!-- See http://github.com/faniereynders/webapiproxy for documentation on using this configuration file --><proxy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"name="MyWebApiProxy"xsi:noNamespaceSchemaLocation="http://webapiproxy.github.io/schemas/client-config.xsd"namespace="WebApi.Proxies"generateAsyncReturnTypes="true"endpoint="http://localhost:801/api/proxies"
/>
nuget程序包管理器控制台中执行以下命令: WebApiProxy-Generate-CSharp,会自动生成客户端调用的代码。
Program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Ohye.Film.ApiClient
{class Program{static void Main(string[] args){WebApi.Proxies.Clients.FilmClient filmClient = new WebApi.Proxies.Clients.FilmClient();filmClient.GetProductList("").ForEach(p =>{Console.WriteLine($"电影:{p.Name}");});Console.ReadKey();}}
}
运行效果:
第四步
查看调用日志:
欢迎注册或登录查看效果: 点击打开链接