自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}Controller
ActionName:{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
扫描二维码关注公众号,回复:
1837255 查看本文章
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 { };
}
}
}
第二步
启动项目,浏览器中输入: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();
}
}
}
运行效果:
第四步
查看调用日志:
欢迎注册或登录查看效果: 点击打开链接