项目中有一个留言消息接口,接收其他系统的留言和展示留言,参考了网上的一些API验证方法,发现使用通用权限管理系统提供的验证方法最完美(http://www.cnblogs.com/jirigala/p/5506022.html)。

下面将实现的完整思路共享

1、WebApiConfig全局处理

    /// <summary>
/// WebApiConfig
/// 路由基础配置。
///
///
/// 修改记录
///
/// 2016.11.01 版本:2.0 宋彪 对日期格式进行统一处理。
/// 2016.10.30 版本:2.0 宋彪 解决json序列化时的循环引用问题。
/// 2016.10.28 版本:2.0 宋彪 回传响应格式 $format 支持。
/// 2016.09.01 版本:1.0 宋彪 创建。
///
/// 版本:1.0
///
/// <author>
/// <name>宋彪</name>
/// <date>2016.09.01</date>
/// </author>
/// </summary>
public static class WebApiConfig
{
/// <summary>
/// 注册全局配置服务
/// </summary>
/// <param name="config"></param>
public static void Register(HttpConfiguration config)
{
// Web API configuration and services //强制https访问
//config.Filters.Add(new ForceHttpsAttribute());
// 统一回传格式
config.Filters.Add(new ApiResultAttribute());
// 发生异常时处理
config.Filters.Add(new ApiErrorHandleAttribute());
// ToKen身份验证过滤器 更方便 不需要在这里了 具有改标签的就会自动检查
//config.Filters.Add(new ApiAuthFilterAttribute());
// 解决json序列化时的循环引用问题
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
//对日期格式进行统一处理
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
new IsoDateTimeConverter()
{
DateTimeFormat = "yyyy-MM-dd hh:mm:ss"
}
); // Web API routes 路由
config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
); // 干掉XML序列化器
//config.Formatters.Remove(config.Formatters.XmlFormatter);
//在请求的Url加上 ?$format=xml,便可以指定响应格式
config.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml");
config.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json");
}
}

2、身份验证过滤器

    using DotNet.Business;
using DotNet.Utilities;
using DotNet.Tracking.API.Common; /// <summary>
/// ApiAuthFilterAttribute
/// 身份验证过滤器,具有ApiAuthFilterAttribute标签属性的方法会自动检查
///
///
/// 修改纪录
///
/// 2016-10-11 版本:1.0 SongBiao 创建文件。
///
/// <author>
/// <name>SongBiao</name>
/// <date>2016-10-11</date>
/// </author>
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class ApiAuthFilterAttribute : AuthorizationFilterAttribute
{
/// <summary>
/// 未授权时的提示信息
/// </summary>
private const string UnauthorizedMessage = "请求未授权,拒绝访问。"; /// <summary>
/// 权限进入
/// </summary>
/// <param name="actionContext"></param>
public override void OnAuthorization(HttpActionContext actionContext)
{
base.OnAuthorization(actionContext);
// 允许匿名访问
if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > )
{
return;
} string systemCode = APIOperateContext.Current.SystemCode;
string permissionCode = APIOperateContext.Current.PermissionCode;
string appKey = APIOperateContext.Current.AppKey;
string appSecret = APIOperateContext.Current.AppSecret;
if (string.IsNullOrWhiteSpace(appKey) || string.IsNullOrWhiteSpace(appSecret))
{
//未验证(登录)的用户, 而且是非匿名访问,则转向登录页面
//actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
//actionContext.Response.Content = new StringContent("<p>Unauthorized</p>", Encoding.UTF8, "text/html");
var response = actionContext.Response= actionContext.Response?? new HttpResponseMessage();
response.StatusCode = HttpStatusCode.Unauthorized;
BaseResult result = new BaseResult
{
Status = false,
StatusMessage = UnauthorizedMessage
};
response.Content = new StringContent(result.ToJson(), Encoding.UTF8, "application/json");
}
else
{
// 检查 AppKey 和 AppSecret
BaseResult result = BaseServicesLicenseManager.CheckService(appKey, appSecret, false, , , systemCode, permissionCode);
if (!result.Status)
{
var response = actionContext.Response = actionContext.Response?? new HttpResponseMessage();
response.Content = new StringContent(result.ToJson(), Encoding.UTF8, "application/json");
}
} }
}

3、统一回传格式

    /// <summary>
/// ApiResultAttribute
/// 统一回传格式
///
/// 修改纪录
///
/// 2016-10-31 版本:1.0 宋彪 创建文件。
///
/// <author>
/// <name>宋彪</name>
/// <date>2016-10-31</date>
/// </author>
/// </summary>
public class ApiResultAttribute : ActionFilterAttribute
{
/// <summary>
/// 重写回传的处理
/// </summary>
/// <param name="actionExecutedContext"></param>
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
// 快件跟踪接口传的是format,不用走这里
if (actionExecutedContext.Request.Properties.ContainsKey("format"))
{
// 若发生例外则不在这边处理 在异常中处理 ApiErrorHandleAttribute
if (actionExecutedContext.Exception != null)
return;
base.OnActionExecuted(actionExecutedContext);
var result = new ApiResultModel();
// 取得由 API 返回的状态码
result.Status = actionExecutedContext.ActionContext.Response.StatusCode;
// 取得由 API 返回的资料
result.Data = actionExecutedContext.ActionContext.Response.Content.ReadAsAsync<object>().Result;
// 重新封装回传格式
actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(result.Status, result);
}
}
}

4、全局异常处理

    using DotNet.Utilities;
using DotNet.Tracking.API.Common;
using DotNet.Tracking.API.Controllers;
using DotNet.Tracking.API.Models; /// <summary>
/// ApiErrorHandleAttribute
/// 全局异常处理
///
/// 修改纪录
///
/// 2016-10-31 版本:1.0 宋彪 创建文件。
///
/// <author>
/// <name>宋彪</name>
/// <date>2016-10-31</date>
/// </author>
/// </summary> public class ApiErrorHandleAttribute : System.Web.Http.Filters.ExceptionFilterAttribute
{
/// <summary>
/// 异常统一处理
/// </summary>
/// <param name="actionExecutedContext"></param>
public override void OnException(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
{
base.OnException(actionExecutedContext);
// 取得发生例外时的错误讯息
var errorMessage = actionExecutedContext.Exception.Message; // 异常记录
string parameters = APIOperateContext.GetRequestParameters();
NLogHelper.Trace(actionExecutedContext.Exception, BaseSystemInfo.SystemCode + " ApiErrorHandleAttribute OnException 完整的请求地址及参数 : " + parameters);
// 2016-11-01 加入异常邮件提醒
NLogHelper.InfoMail(actionExecutedContext.Exception, BaseSystemInfo.SystemCode + " ApiErrorHandleAttribute OnException 完整的请求地址及参数 : " + parameters); var result = new ApiResultModel()
{
Status = HttpStatusCode.BadRequest,
ErrorMessage = errorMessage
};
// 重新打包回传的讯息
actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(result.Status, result);
}
}

5、接口操作的上下文

    using DotNet.Business;
using DotNet.Model;
using DotNet.Utilities; /// <summary>
/// APIOperateContext
/// 接口操作的上下文
/// 跟上下文有关的一些通用的东西放在这里处理
///
/// 修改纪录
///
/// 2016-10-31 版本:1.0 宋彪 创建文件。
///
/// <author>
/// <name>宋彪</name>
/// <date>2016-10-31</date>
/// </author>
/// </summary>
public class APIOperateContext
{
/// <summary>
/// 获取当前 操作上下文 (为每个处理浏览器请求的服务器线程 单独创建 操作上下文)
/// </summary>
public static APIOperateContext Current
{
get
{
APIOperateContext oContext = CallContext.GetData(typeof(APIOperateContext).Name) as APIOperateContext;
if (oContext == null)
{
oContext = new APIOperateContext();
CallContext.SetData(typeof(APIOperateContext).Name, oContext);
}
return oContext;
}
} #region Http上下文 及 相关属性
/// <summary>
/// Http上下文
/// </summary>
public HttpContext ContextHttp
{
get
{
return HttpContext.Current;
}
} /// <summary>
/// 输出对象
/// </summary>
public HttpResponse Response
{
get
{
return ContextHttp.Response;
}
} /// <summary>
/// 请求对象
/// </summary>
public HttpRequest Request
{
get
{
return ContextHttp.Request;
}
} /// <summary>
/// Session对象
/// </summary>
System.Web.SessionState.HttpSessionState Session
{
get
{
return ContextHttp.Session;
}
}
#endregion /// <summary>
/// 获取全部请求参数,get和post的 简化版
/// </summary>
public static string GetRequestParameters()
{
string query = HttpContext.Current.Request.Url.Query;
NameValueCollection nvc;
string baseUrl;
ParseUrl(query, out baseUrl, out nvc);
List<string> list = new List<string>() { };
foreach (var key in nvc.AllKeys)
{
list.Add(key + "=" + nvc[key]);
} var form = HttpContext.Current.Request.Form;
foreach (var key in form.AllKeys)
{
list.Add(key + "=" + form[key]);
}
string result = HttpContext.Current.Request.Url.AbsoluteUri + "?" + string.Join("&", list); return result;
} /// <summary>
/// 分析 url 字符串中的参数信息
/// 针对get请求的
/// </summary>
/// <param name="url">输入的 URL</param>
/// <param name="baseUrl">输出 URL 的基础部分</param>
/// <param name="nvc">输出分析后得到的 (参数名,参数值) 的集合</param>
public static void ParseUrl(string url, out string baseUrl, out NameValueCollection nvc)
{
if (url == null)
{
throw new ArgumentNullException("url");
}
nvc = new NameValueCollection();
baseUrl = "";
if (url == "")
{
return;
}
int questionMarkIndex = url.IndexOf('?');
if (questionMarkIndex == -)
{
baseUrl = url;
return;
}
baseUrl = url.Substring(, questionMarkIndex);
if (questionMarkIndex == url.Length - )
{
return;
}
string ps = url.Substring(questionMarkIndex + );
// 开始分析参数对
Regex re = new Regex(@"(^|&)?(\w+)=([^&]+)(&|$)?", RegexOptions.Compiled);
MatchCollection mc = re.Matches(ps);
foreach (Match m in mc)
{
nvc.Add(m.Result("$2").ToLower(), m.Result("$3"));
}
} /// <summary>
/// 系统编号
/// </summary>
public string SystemCode
{
get
{
return Request["systemCode"] ?? "Base";
}
} /// <summary>
/// 权限编号
/// </summary>
public string PermissionCode
{
get
{
return Request["permissionCode"];
}
} /// <summary>
/// 访问接口的应用传来AppKey
/// </summary>
public string AppKey
{
get
{
return Request["appKey"];
}
} /// <summary>
/// 访问接口的应用传来AppSecret
/// </summary>
public string AppSecret
{
get
{
return Request["appSecret"];
}
} private BaseUserInfo _userInfo = null;
/// <summary>
/// 获取当前用户
/// 通过接口AppKey和AppSecret获取的用户
/// </summary>
/// <returns></returns>
public BaseUserInfo UserInfo
{
get
{
BaseUserInfo userInfo = null;
BaseUserEntity userEntity = BaseUserManager.GetObjectByCodeByCache(AppKey);
if (userEntity != null)
{
if (BaseServicesLicenseManager.CheckServiceByCache(userEntity.Id, AppSecret))
{
userInfo = new BaseUserInfo();
userInfo.Id = userEntity.Id;
userInfo.RealName = userEntity.RealName;
userInfo.UserName = userEntity.UserName;
userInfo.IPAddress = Utilities.GetIPAddress(true);
}
}
return userInfo;
}
} #region 业务库连接
/// <summary>
/// 业务库连接
/// </summary>
public static IDbHelper BusinessDbHelper
{
get
{
return DbHelperFactory.GetHelper(BaseSystemInfo.BusinessDbType, BaseSystemInfo.BusinessDbConnection);
}
}
#endregion #region 用户中心库连接
/// <summary>
/// 用户中心库连接
/// </summary>
public static IDbHelper UserCenterDbHelper
{
get
{
return DbHelperFactory.GetHelper(BaseSystemInfo.UserCenterDbType, BaseSystemInfo.UserCenterDbConnection);
}
}
#endregion }

7、统一回传格式实体

    /// <summary>
/// ApiResultModel
/// 统一回传格式实体
///
/// 修改纪录
///
/// 2016-10-31 版本:1.0 宋彪 创建文件。
///
/// <author>
/// <name>宋彪</name>
/// <date>2016-10-31</date>
/// </author>
/// </summary>
public class ApiResultModel
{
public HttpStatusCode Status { get; set; } //public JsonResult<T> Data { get; set; }
public object Data { get; set; }
public string ErrorMessage { get; set; }
}

8、留言相关接口

    /// <summary>
/// MessageBookController
/// 留言相关接口
///
/// 修改纪录
///
/// 2016-10-31 版本:1.0 宋彪 创建文件。
///
/// <author>
/// <name>宋彪</name>
/// <date>2016-10-31</date>
/// </author>
/// </summary>
[ApiAuthFilter]
public class CustomerMessageController : ApiController
{
/// <summary>
/// 保存单号留言信息
/// </summary>
/// <param name="messageBook"></param>
/// <returns></returns>
[HttpPost]
//[AllowAnonymous] 不需要验证的就加这个标签
public IHttpActionResult Add([FromBody]MsgbookCusEntity messageBook)
{
BaseResult baseResult = new BaseResult();
if (string.IsNullOrWhiteSpace(messageBook.SystemFrom))
{
baseResult.Status = false;
baseResult.StatusMessage = "SystemFrom参数不可为空";
}
else
{
try
{
MsgbookCusManager manager = new MsgbookCusManager(APIOperateContext.BusinessDbHelper, APIOperateContext.Current.UserInfo);
MsgbookCusEntity model = new MsgbookCusEntity();
model.Id = Guid.NewGuid().ToString("N");
model.Message = messageBook.Message;
model.SendEmail = messageBook.SendEmail;
model.SendTelephone = messageBook.SendTelephone;
model.Message = messageBook.Message;
model.BillCode = messageBook.BillCode;
model.SystemFrom = messageBook.SystemFrom;
model.DeletionStateCode = ;
manager.Add(model, false, false); baseResult.Status = true;
baseResult.StatusMessage = "添加成功。";
}
catch (Exception ex)
{
NLogHelper.Warn(ex, "CustomerMessageController AddBillMessage 异常");
baseResult.Status = false;
baseResult.StatusMessage = "异常:" + ex.Message;
}
} return Ok(baseResult);
} /// <summary>
/// 获取某个单号的留言
/// </summary>
/// <param name="billCode"></param>
/// <returns></returns>
[HttpGet]
public IHttpActionResult GetList(string billCode)
{
JsonResult<List<MsgbookCusEntity>> jsonResult = new JsonResult<List<MsgbookCusEntity>>();
try
{
MsgbookCusManager manager = new MsgbookCusManager(APIOperateContext.BusinessDbHelper, APIOperateContext.Current.UserInfo);
List<MsgbookCusEntity> list = new List<MsgbookCusEntity>();
list = manager.GetList<MsgbookCusEntity>(new KeyValuePair<string, object>(MsgbookCusEntity.FieldBillCode, billCode)
, new KeyValuePair<string, object>(MsgbookCusEntity.FieldDeletionStateCode, )); jsonResult.Status = true;
jsonResult.RecordCount = list.Count;
jsonResult.Data = list;
jsonResult.StatusMessage = "获取成功";
}
catch (Exception ex)
{
NLogHelper.Warn(ex, "CustomerMessageController AddBillMessage 异常");
jsonResult.Status = false;
jsonResult.StatusMessage = "异常:" + ex.Message;
} return Ok(jsonResult);
}
}

9、接口调用方法

        /// <summary>
/// 测试留言接口调用
/// </summary>
/// <returns></returns>
public ActionResult AddCustomerMessage()
{
string url = "http://192.168.1.88:808/api/CustomerMessage/Add?";
WebClient webClient = new WebClient();
NameValueCollection postValues = new NameValueCollection(); postValues.Add("Message", "填写您的留言内容吧");
postValues.Add("SendEmail", "youemail@qq.com");
postValues.Add("SendTelephone", "021-60375335");
postValues.Add("Code", "");
postValues.Add("AppKey", "wssavbcn");
postValues.Add("AppSecret", "350e66b1e6564b0a817163erwwwwe8");
postValues.Add("SystemFrom", "官网"); byte[] responseArray = webClient.UploadValues(url, postValues);
string response = Encoding.UTF8.GetString(responseArray); return Content(response);
}

ASP.NET MVC API 接口验证的更多相关文章

  1. asp.net mvc ,asp.net mvc api 中使用全局过滤器进行异常捕获记录

    MVC下的全局异常过滤器注册方式如下:标红为asp.net mvc ,asp.net mvc api  注册全局异常过滤器的不同之处 using SuperManCore; using System. ...

  2. 一百元的智能家居——Asp.Net Mvc Api+讯飞语音+Android+Arduino

    大半夜的,先说些废话提提神 如今智能家居已经不再停留在概念阶段,高大上的科技公司都已经推出了自己的部分或全套的智能家居解决方案,不过就目前的现状而言,大多还停留在展厅阶段,还没有广泛的推广起来,有人说 ...

  3. ASP.NET Web API 接口执行时间监控

    软件产品常常会出现这样的情况:产品性能因某些无法预料的瓶颈而受到干扰,导致程序的处理效率降低,性能得不到充分的发挥.如何快速有效地找到软件产品的性能瓶颈,则是我们感兴趣的内容之一. 在本文中,我将解释 ...

  4. ASP.NET MVC API 路由生成规则

    我们都知道调用ASP.NET MVC的某些API函数(诸如:Url.Action.RedirectToAction等)可以生成URL,ASP.NET MVC会根据调用API函数时传入的参数去匹配系统定 ...

  5. Asp.Net Web Api 接口,拥抱支持跨域访问。

    如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问. 由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的问题 ...

  6. Asp.Net Web Api 接口

    如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问.   由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的 ...

  7. asp.net mvc+httpclient+asp.net mvc api入门篇

    第一步:创建一个ASP.NET MVC API项目 第二步:在api项目里面创建一个类 public class Student { public int Id { get; set; } publi ...

  8. ASP.NET MVC API与JS进行POST请求时传递参数 -CHPowerljp原创

    在API前添加    [HttpPost] 表示只允许POST方式请求 [HttpPost] public IHttpActionResult Get_BIGDATA([FromBody]Datas  ...

  9. ASP.NET MVC WebApi接口授权验证

    对于很任何多开发者来说,不管是使用任何一种框架,或者是使用任何一种语言,都要使用面向接口编程.使用面向接口编程的时候,那么就会有很多的权限验证,用户验证等等. 特别是对于一些系统来说,别人想要对接你的 ...

随机推荐

  1. Digitalocean + ss 搭建加密通信代理服务器

    本文以 DigitalOcean + ss/ssr 配置加密通道***为例,记录了手动搭梯子的过程. 启动一个服务器实例的操作可以参考我的这篇博文,这里主要介绍 ss/ssr 的服务搭建过程. 首先 ...

  2. Mac下基于testrpc和truffle的以太坊智能合约开发环境搭建

    原文地址:石匠的blog truffle是一个基于Javascript开发的一套智能合约开发框架,使用Solidity语言编写合约.truffle有一套自动的项目构建机制,集成了开发,测试和部署的各个 ...

  3. 笨办法学Python - 习题1: A Good First Program

    在windows上安装完Python环境后,开始按照<笨办法学Python>书上介绍的章节进行练习. 习题 1: 第一个程序 第一天主要是介绍了Python中输出函数print的使用方法, ...

  4. python 输出格式化之后的时间格式

    import timetime.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

  5. jenkins部署时遇到“似乎无法联网”,导致无法安装默认插件的解决方案

    jenkins安装更新时,默认会检查网络连接,而默认的checkulr 是http://www.google.com/ ,国内是无法访问的,所以修改成任意可以访问的地址即可,比如http://www. ...

  6. 升级Xcode 10 后报错问题记录([CP] Copy Pods Resources)

    1.升级Xcode到Version 10.0 (10A255)后,运行已有项目,报如下错误: error: Multiple commands produce '/Users/galahad/Libr ...

  7. centos7安装oracle亲测可用

    http://www.linuxidc.com/Linux/2016-04/130559p2.htm

  8. 20lanmo162326 2017-2018-1 《程序设计与数据结构》第1周学习总结

    20162326 2017-2018-1 <程序设计与数据结构>第1周学习总结 教材学习内容总结 算法:在特定计算模型下,解决问题的指令序列 计算 = 信息处理 也就是用工具,遵规则,机械 ...

  9. 福大软工1816 · 评分结果 · Alpha冲刺

    作业地址:alpha冲刺1.alpha冲刺2.alpha冲刺3.alpha冲刺4.alpha冲刺5.alpha冲刺6.alpha冲刺7.alpha冲刺8.alpha冲刺9.alpha冲刺10 作业提交 ...

  10. Week2-作业1-part2.阅读与思考

    第一章.概论 原文: 在成熟的航空工业中,一个飞机发动机从构思到最后运行,不知道经历过多少人.多少工序.多少流程.多少相关知识的验证.我们无法想象,某个商用型号的发动机在飞行时发现问题,最初的设计师会 ...