特性是什么
特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。说白了它只是继承了Attrbute的一个类。
实际使用
这边做一个调用接口开始和结束写入日志的应用
public class HelpAttribute : ActionFilterAttribute
{
public HelpAttribute() { }
private string requestFilter1 = string.Empty;
/// <summary>
/// 过滤字段1
/// </summary>
public string RequestFilter1
{
get
{
return requestFilter1;
}
set
{
requestFilter1 = value;
}
}
private string requestFilter2 = string.Empty;
/// <summary>
/// 过滤字段2
/// </summary>
public string RequestFilter2
{
get
{
return requestFilter2;
}
set
{
requestFilter2 = value;
}
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext);
try
{
WriteRequestLog(actionContext);
}
catch
{
}
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
try
{
WriteResponseLog(actionExecutedContext);
}
catch
{
}
}
log4net.ILog log = log4net.LogManager.GetLogger("testApp.Logging");
private void WriteRequestLog(HttpActionContext actionContext)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
//控制器名
string controlName = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
//Action名
string actName = actionContext.ActionDescriptor.ActionName;
//过滤字段1
string valFilter1 = string.Empty;
//过滤字段2
string valFilter2 = string.Empty;
string requestContent = string.Empty;
string requestUrl = actionContext.Request.RequestUri.ToString();
var sm = HttpContext.Current.Request.InputStream;
sm.Seek(0, SeekOrigin.Begin);
byte[] data = new byte[sm.Length];
sm.Read(data, 0, data.Length);
requestContent = Encoding.UTF8.GetString(data);
if (!string.IsNullOrEmpty(requestContent))
{
JObject reqJobject = JObject.Parse(requestContent);
if (!string.IsNullOrEmpty(RequestFilter1))
valFilter1 = reqJobject[RequestFilter1]?.ToString();
if (!string.IsNullOrEmpty(RequestFilter2))
{
string _inputtext = reqJobject["InputText"]?.ToString();
JObject jo2 = JObject.Parse(_inputtext);
valFilter2 = jo2[RequestFilter2]?.ToString();
}
}
HttpContext.Current.Items["controlName"] = controlName;
HttpContext.Current.Items["actName"] = actName;
HttpContext.Current.Items["valFilter1"] = valFilter1;
HttpContext.Current.Items["valFilter2"] = valFilter2;
HttpContext.Current.Items["stopWatch"] = stopWatch;
Task.Run(() =>
{
string msg = string.Format("请求开始,控制器名称:{0},方法名:{1},来源渠道:{2},单号:{3},请求内容:{4}", controlName, actName, valFilter1, valFilter2, requestContent);
log.Info(msg);
});
}
private void WriteResponseLog(HttpActionExecutedContext actionExecutedContext)
{
//控制器名
string controlName = HttpContext.Current.Items["controlName"]?.ToString();
//Action名
string actName = HttpContext.Current.Items["actName"]?.ToString();
//过滤字段1
string valFilter1 = HttpContext.Current.Items["valFilter1"]?.ToString();
//过滤字段2
string valFilter2 = HttpContext.Current.Items["valFilter2"]?.ToString();
string timespend = string.Empty;
Stopwatch sw = HttpContext.Current.Items["stopWatch"] as Stopwatch;
if (sw != null)
{
sw.Stop();
timespend = sw.ElapsedMilliseconds.ToString();
}
Task.Run(() =>
{
string responseContent = actionExecutedContext.Response.Content.ReadAsStringAsync().Result;
string msg = string.Format("请求结束,控制器名称:{0},方法名:{1},来源渠道:{2},单号:{3},请求时长:{4},返回信息:{5}", controlName, actName, valFilter1, valFilter2, timespend, responseContent);
log.Info(msg);
});
}
}
写入日志用的事log4net,这边暂不做讨论。这个特性主要是继承ActionFilterAttribute并重写了方法OnActionExecuting(在调用操作之前发生)和OnActionExecuted(在调用操作之后发生)
例如我在控制器中放入特性
```
public class TestController : ApiController
{
[HttpPost]
[HelpAttribute(RequestFilter1 = "Channel", RequestFilter2 = "Serialid")]
public string Test([FromBody]BasicRequest req)
{
return "hello curry";
}
}
public class BasicRequest
{
public ChannelEnum Channel { get; set; }
public string InputText { get; set; }
}
public enum ChannelEnum
{
App = 1,
WX = 2,
PC = 3,
}
```
请求接口后
查看日志
完成