目录

本周工作的时候,任务计划已经完成,进行了接口的调优,其中对于过滤器这一块着重进行了调整。

在这个过程中对过滤器的顺序有了一定了解,这里记录下来。

1、身份认证过滤器—AuthenticationFilter

这个是做统一身份认证授权的,这个是最先进来的,进行用户身份验证:

public class BasicAuthenticationFilterAttribute : FilterAttribute, IAuthenticationFilter
{
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
if (context.ActionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
{
return Task.FromResult();
} // 具体认证业务逻辑
} public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
string realm = context.Request.RequestUri.DnsSafeHost;
context.Result = new AddBasicChallengeResult(context.Result, realm);
return Task.FromResult();
} // 错误信息生成
public class AuthenticationFailureResult : IHttpActionResult
{
public AuthenticationFailureResult(HttpRequestMessage request)
{
Request = request;
} public HttpRequestMessage Request { get; private set; } public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Execute());
} private HttpResponseMessage Execute()
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
RequestMessage = Request
};
return response;
}
} // 认证失败返回质询信息
private class AddBasicChallengeResult : IHttpActionResult
{
private IHttpActionResult innerResult;
private string realm; public AddBasicChallengeResult(IHttpActionResult innerResult, string realm)
{
this.innerResult = innerResult;
this.realm = realm;
} public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = await innerResult.ExecuteAsync(cancellationToken);
if (response.StatusCode == HttpStatusCode.Unauthorized)
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Basic", String.Format("realm=\"{0}\"", realm)));
return response;
}
}
}

2、Action 过滤器—ActionFilter

这个是对操作进行统一过滤的过滤器,在这个过滤器里面可以做的事情就很多,我们这里用到了:模型验证、请求信息记录、返回信息格式化;

在这里就分别说下几个具体的业务逻辑;

A、请求信息记录—RequestLogFilter

这里的记录接口请求信息,记录下每个接口请求详情,便于查看记录,具体代码:

public class RequestLogFilterAttribute : ActionFilterAttribute
{
private readonly string Key = "_RequestTime_";
private readonly string Watch = "_Stopwatch_";
private readonly string Token = ConfigurationManager.AppSettings["Token"].ToString(); public override void OnActionExecuting(HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext); Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
actionContext.Request.Properties[Key] = DateTime.Now;
actionContext.Request.Properties[Watch] = stopWatch;
} public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
Stopwatch stopWatch = actionExecutedContext.Request.Properties[Watch] as Stopwatch;
stopWatch.Stop(); // 如果有该特性就不记录请求记录(绕过记录)
if (actionExecutedContext.ActionContext.ActionDescriptor.GetCustomAttributes<BypassRequestLogFilterAttribute>().Any())
{
return;
} // 具体记录接口请求信息
}
}

B、模型验证—ValidateModelFilter

这个是模型验证的,对接口的数据有效性进行验证

public class ValidateModelFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ModelState.IsValid == false)
{
List<Dictionary<string, string>> allErrors = new List<Dictionary<string, string>>();
var modelState = actionContext.ModelState;
foreach (var key in modelState.Keys)
{
Dictionary<string, string> errorDictionary = new Dictionary<string, string>();
var state = modelState[key];
string[] errorMessages = state.Errors.Select(t => t.ErrorMessage).ToArray();
errorDictionary.Add(key, string.Join(",", errorMessages)); allErrors.Add(errorDictionary);
} ResponseData responseData = new ResponseData { MsgCode = , Message = "参数有误!", Data = allErrors };
JsonMediaTypeFormatter jsonMediaTypeFormatter = actionContext.Request.GetConfiguration().Formatters.JsonFormatter; actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, responseData, jsonMediaTypeFormatter);
}
}
}

C、返回信息格式化—ResponseFormatterFilter

之所以添加这个过滤器是在我们手机端调用接口的时候,发现返回的信息不是定义好的,

是经过了一种格式化,不能按照我们既定的格式进行解析(分析发现,是请求的时候格式化,返回的信息也按照这个格式化),

所以在过滤器里再对全部的返回信息进行格式化:

public class ResponseFormatterFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Response != null && actionExecutedContext.Response.IsSuccessStatusCode)
{
ObjectContent content = actionExecutedContext.Response.Content as ObjectContent;
JsonMediaTypeFormatter jsonMediaTypeFormatter = actionExecutedContext.Request.GetConfiguration().Formatters.JsonFormatter; actionExecutedContext.Response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new ObjectContent(content.Value.GetType(), content.Value, jsonMediaTypeFormatter)
};
}
}
}

这几个都是继承自:ActionFilterAttribute,为了比较清晰所以分开放。

对于这种同一级别的过滤器,其执行的先后顺序是:注册在前的先进后出,注册在后的后进先出(大致如下图)

3、异常处理过滤器—ExceptionFilterAttribute

这个是统一处理有异常的过滤器,多错误过滤,返回给客户端的是处理过的,也是最后面一个出去的,过滤器里面有错误也会捕捉到。

具体代码:

public class ExceptionLogFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
base.OnException(actionExecutedContext); JsonMediaTypeFormatter jsonMediaTypeFormatter = actionExecutedContext.Request.GetConfiguration().Formatters.JsonFormatter;
ResponseData responseData; if (actionExecutedContext.Exception is ExceptionEx)
{
responseData = new ResponseData { MsgCode = , Message = actionExecutedContext.Exception.Message };
}
else
{
Exception exceptionData = null; if (ConfigurationManager.AppSettings["ApplicationEnvironment"] == ApplicationEnvironmentEnum.Development.ToString())
{
exceptionData = actionExecutedContext.Exception;
} responseData = new ResponseData { MsgCode = , Message = "系统内部异常!请联系管理员!", Data = exceptionData }; } actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.BadRequest, responseData, jsonMediaTypeFormatter);
}
}

对于不同级别的过滤器,执行顺序是:

AuthenticationFilter > ActionFilterAttribute > ExceptionFilterAttribute

4、IIS WebDAV 模块

在每次发布后,出现一个问题:跨域和Put请求不了。

对于这个问题,是已经配置过的怎么还会出现这个问题。

经过反复的测试,原来是 IIS WebDAV 模块,虽然配置了,IIS 是直接修改 Webconfig 文件的,再次发布覆盖了这个文件原有的配置就没了。

对于这个问题,可以在 Webconfig 文件里面配置上,这样可以。

也可以直接去掉 WebDAV 模块,但是卸载不好卸载。可以在 IIS 站点配置文件里面删除 WebDAV 的配置,这样也可以达到效果。

接口调优——WebAPI 过滤器,IIS WebDAV的更多相关文章

  1. 记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?)

    记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?) 前几天帮客户优化一个数据库,那个数据库的大小是6G 这麽小的数据库按道理不会有太大的性能问题的, ...

  2. [网站性能2]Asp.net平台下网站性能调优的实战方案

    文章来源:http://www.cnblogs.com/dingjie08/archive/2009/11/10/1599929.html 前言    最近帮朋友运营的平台进行了性能调优,效果还不错, ...

  3. Asp.net平台下网站性能调优的实战方案(转)

    转载地址:http://www.cnblogs.com/chenkai/archive/2009/11/07/1597795.html 前言 最近帮朋友运营的平台进行了性能调优,效果还不错,所以写出来 ...

  4. 记一次Web服务的性能调优

    前言 一个项目在经历开发.测试.上线后,当时的用户规模还比较小,所以刚刚上线的项目一般会表现稳定.但是随着时间的推移,用户数量的增加,qps的增加等因素会造成项目慢慢表现出网页半天无响应的状况.在之前 ...

  5. 一个简单web系统的接口性能分析及调优过程

    在测试一个简单系统接口性能压力时,压到一定数量,程序总是崩溃,查看相关机器相关数据时,CPU.内存.IO占用均不高,问题自然出现在其它地方先介绍下系统部件架构 Resin版本为:[root@local ...

  6. C# WebApi 过滤器的使用开发接口必备利器

    在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想 ...

  7. Nginx源码安装及调优配置

    导读 由于Nginx本身的一些优点,轻量,开源,易用,越来越多的公司使用nginx作为自己公司的web应用服务器,本文详细介绍nginx源码安装的同时并对nginx进行优化配置. Nginx编译前的优 ...

  8. 《深入理解Java虚拟机》-----第5章 jvm调优案例分析与实战

    案例分析 高性能硬件上的程序部署策略 例 如 ,一个15万PV/天左右的在线文档类型网站最近更换了硬件系统,新的硬件为4个CPU.16GB物理内存,操作系统为64位CentOS 5.4 , Resin ...

  9. java大数据量调优

    从总体上来看,对于大型网站,比如门户网站,在面对大量用户访问.高并发请求方面,基本的解决方案集中在这样几个环节:1.首先需要解决网络带宽和Web请求的高并发,需要合理的加大服务器和带宽的投入,并且需要 ...

随机推荐

  1. Consul 快速入门 - Kong最佳实践

    Consul是什么 Consul是一个服务网格(微服务间的 TCP/IP,负责服务之间的网络调用.限流.熔断和监控)解决方案,它是一个一个分布式的,高度可用的系统,而且开发使用都很简便.它提供了一个功 ...

  2. 【Chrome插件】Session Buddy--搁置标签页

    写在前面:看文章前请先看文章写作时间,避免浪费时间.2019-09-10 使用场景 Chrome打开许多网页,临时有事需要把当前的一些标签页一键保存,等待事后继续处理. 操作演示 原片地址:https ...

  3. 【GStreamer开发】GStreamer基础教程05——集成GUI工具

    目标 本教程展示了如何在GStreamer集成一个GUI(比如:GTK+).最基本的原则是GStreamer处理多媒体的播放而GUI处理和用户的交互. 在这个教程里面,我们可以学到: 如何告诉GStr ...

  4. 最新 博盾习言java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿. 博盾习言等10家互联网公司的校招Offer,因为某些自身原因最终选择了 博盾习言.6.7月主要是做系统复习.项目复盘.Le ...

  5. MApp_ZUI_CTL_MarqueeTextWinProc字串滚动

    /////////////////////////////////////////////////////////////////////////////// /// global MApp_ZUI_ ...

  6. 011 Android AutoCompleteTextView(自动完成文本框)的基本使用

    1.XML布局 android:completionThreshold="1":这里我们设置了输入一个字就显示提示 (1)主界面布局 <?xml version=" ...

  7. java中selenium判断某个元素是否存在

    selenium工具 直接通过findElement方法获取某个元素,如果该元素不存在肯定会报错,selenium又没有可以判断该元素是否存在的方法 于是我们可以手写一个工具类,来判断这个元素是否存在 ...

  8. Linux02 cd命令以及绝对路径和相对路径

    一.cd 这是一个非常基本,也是大家常用的命令,用于切换当前目录,他的参数就是要切换的目录的路径,可以是绝对路径,也可以是相对路径. cd /home/keshengtao/ 绝对路径 cd ./pa ...

  9. Python31之类和对象1(三大特征:多封继——多疯子)

    一.对象: Python即是面向对象的编程也是面向过程的编程语言,其内部可谓是无处不对象,我们所熟知的列表,字符串等工厂函数本质上都是对象.对象其实是对属性和方法的封装. 属性是对象的静态特征 方法是 ...

  10. 史上最全最新java面试题合集二(附答案)

    下面小编整理了本套java面试题全集,分享给大家,希望对大家的java学习和就业面试有所帮助. 51.类ExampleA继承Exception,类ExampleB继承ExampleA. 有如下代码片断 ...