ASP.NET MVC API 接口验证的示例代码
项目中有一个留言消息接口,接收其他系统的留言和展示留言,参考了网上的一些API验证方法,发现使用通用权限管理系统提供的验证方法最完美。
下面将实现的完整思路共享
1、WebApiConfig全局处理
//////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 /// /// publicstaticclassWebApiConfig { ////// ///宋彪 ///2016.09.01 //////注册全局配置服务 /// ///publicstaticvoidRegister(HttpConfigurationconfig) { //WebAPIconfigurationandservices //强制https访问 //config.Filters.Add(newForceHttpsAttribute()); //统一回传格式 config.Filters.Add(newApiResultAttribute()); //发生异常时处理 config.Filters.Add(newApiErrorHandleAttribute()); //ToKen身份验证过滤器更方便不需要在这里了具有改标签的就会自动检查 //config.Filters.Add(newApiAuthFilterAttribute()); //解决json序列化时的循环引用问题 config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling=Newtonsoft.Json.ReferenceLoopHandling.Ignore; //对日期格式进行统一处理 config.Formatters.JsonFormatter.SerializerSettings.Converters.Add( newIsoDateTimeConverter() { DateTimeFormat="yyyy-MM-ddhh:mm:ss" } ); //WebAPIroutes路由 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、身份验证过滤器
usingDotNet.Business; usingDotNet.Utilities; usingDotNet.Tracking.API.Common; //////ApiAuthFilterAttribute ///身份验证过滤器,具有ApiAuthFilterAttribute标签属性的方法会自动检查 /// /// ///修改纪录 /// ///2016-10-11版本:1.0SongBiao创建文件。 /// /// [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,Inherited=true,AllowMultiple=true)] publicclassApiAuthFilterAttribute:AuthorizationFilterAttribute { ////// ///SongBiao ///2016-10-11 //////未授权时的提示信息 /// privateconststringUnauthorizedMessage="请求未授权,拒绝访问。"; //////权限进入 /// ///publicoverridevoidOnAuthorization(HttpActionContextactionContext) { base.OnAuthorization(actionContext); //允许匿名访问 if(actionContext.ActionDescriptor.GetCustomAttributes ().Count>0) { return; } stringsystemCode=APIOperateContext.Current.SystemCode; stringpermissionCode=APIOperateContext.Current.PermissionCode; stringappKey=APIOperateContext.Current.AppKey; stringappSecret=APIOperateContext.Current.AppSecret; if(string.IsNullOrWhiteSpace(appKey)||string.IsNullOrWhiteSpace(appSecret)) { //未验证(登录)的用户,而且是非匿名访问,则转向登录页面 //actionContext.Response=actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized); //actionContext.Response.Content=newStringContent(" Unauthorized
",Encoding.UTF8,"text/html"); varresponse=actionContext.Response=actionContext.Response??newHttpResponseMessage(); response.StatusCode=HttpStatusCode.Unauthorized; BaseResultresult=newBaseResult { Status=false, StatusMessage=UnauthorizedMessage }; response.Content=newStringContent(result.ToJson(),Encoding.UTF8,"application/json"); } else { //检查AppKey和AppSecret BaseResultresult=BaseServicesLicenseManager.CheckService(appKey,appSecret,false,0,0,systemCode,permissionCode); if(!result.Status) { varresponse=actionContext.Response=actionContext.Response??newHttpResponseMessage(); response.Content=newStringContent(result.ToJson(),Encoding.UTF8,"application/json"); } } } }
3、统一回传格式
//////ApiResultAttribute ///统一回传格式 /// ///修改纪录 /// ///2016-10-31版本:1.0宋彪创建文件。 /// /// publicclassApiResultAttribute:ActionFilterAttribute { ////// ///宋彪 ///2016-10-31 //////重写回传的处理 /// ///publicoverridevoidOnActionExecuted(HttpActionExecutedContextactionExecutedContext) { //快件跟踪接口传的是format,不用走这里 if(actionExecutedContext.Request.Properties.ContainsKey("format")) { //若发生例外则不在这边处理在异常中处理ApiErrorHandleAttribute if(actionExecutedContext.Exception!=null) return; base.OnActionExecuted(actionExecutedContext); varresult=newApiResultModel(); //取得由API返回的状态码 result.Status=actionExecutedContext.ActionContext.Response.StatusCode; //取得由API返回的资料 result.Data=actionExecutedContext.ActionContext.Response.Content.ReadAsAsync
4、全局异常处理
usingDotNet.Utilities; usingDotNet.Tracking.API.Common; usingDotNet.Tracking.API.Controllers; usingDotNet.Tracking.API.Models; //////ApiErrorHandleAttribute ///全局异常处理 /// ///修改纪录 /// ///2016-10-31版本:1.0宋彪创建文件。 /// /// publicclassApiErrorHandleAttribute:System.Web.Http.Filters.ExceptionFilterAttribute { ////// ///宋彪 ///2016-10-31 //////异常统一处理 /// ///publicoverridevoidOnException(System.Web.Http.Filters.HttpActionExecutedContextactionExecutedContext) { base.OnException(actionExecutedContext); //取得发生例外时的错误讯息 varerrorMessage=actionExecutedContext.Exception.Message; //异常记录 stringparameters=APIOperateContext.GetRequestParameters(); NLogHelper.Trace(actionExecutedContext.Exception,BaseSystemInfo.SystemCode+"ApiErrorHandleAttributeOnException完整的请求地址及参数:"+parameters); //2016-11-01加入异常邮件提醒 NLogHelper.InfoMail(actionExecutedContext.Exception,BaseSystemInfo.SystemCode+"ApiErrorHandleAttributeOnException完整的请求地址及参数:"+parameters); varresult=newApiResultModel() { Status=HttpStatusCode.BadRequest, ErrorMessage=errorMessage }; //重新打包回传的讯息 actionExecutedContext.Response=actionExecutedContext.Request.CreateResponse(result.Status,result); } }
5、接口操作的上下文
usingDotNet.Business; usingDotNet.Model; usingDotNet.Utilities; //////APIOperateContext ///接口操作的上下文 ///跟上下文有关的一些通用的东西放在这里处理 /// ///修改纪录 /// ///2016-10-31版本:1.0宋彪创建文件。 /// /// publicclassAPIOperateContext { ////// ///宋彪 ///2016-10-31 //////获取当前操作上下文(为每个处理浏览器请求的服务器线程单独创建操作上下文) /// publicstaticAPIOperateContextCurrent { get { APIOperateContextoContext=CallContext.GetData(typeof(APIOperateContext).Name)asAPIOperateContext; if(oContext==null) { oContext=newAPIOperateContext(); CallContext.SetData(typeof(APIOperateContext).Name,oContext); } returnoContext; } } #regionHttp上下文及相关属性 //////Http上下文 /// publicHttpContextContextHttp { get { returnHttpContext.Current; } } //////输出对象 /// publicHttpResponseResponse { get { returnContextHttp.Response; } } //////请求对象 /// publicHttpRequestRequest { get { returnContextHttp.Request; } } //////Session对象 /// System.Web.SessionState.HttpSessionStateSession { get { returnContextHttp.Session; } } #endregion //////获取全部请求参数,get和post的简化版 /// publicstaticstringGetRequestParameters() { stringquery=HttpContext.Current.Request.Url.Query; NameValueCollectionnvc; stringbaseUrl; ParseUrl(query,outbaseUrl,outnvc); Listlist=newList (){}; foreach(varkeyinnvc.AllKeys) { list.Add(key+"="+nvc[key]); } varform=HttpContext.Current.Request.Form; foreach(varkeyinform.AllKeys) { list.Add(key+"="+form[key]); } stringresult=HttpContext.Current.Request.Url.AbsoluteUri+"?"+string.Join("&",list); returnresult; } /// ///分析url字符串中的参数信息 ///针对get请求的 /// ///输入的URL /// 输出URL的基础部分 /// 输出分析后得到的(参数名,参数值)的集合 publicstaticvoidParseUrl(stringurl,outstringbaseUrl,outNameValueCollectionnvc) { if(url==null) { thrownewArgumentNullException("url"); } nvc=newNameValueCollection(); baseUrl=""; if(url=="") { return; } intquestionMarkIndex=url.IndexOf('?'); if(questionMarkIndex==-1) { baseUrl=url; return; } baseUrl=url.Substring(0,questionMarkIndex); if(questionMarkIndex==url.Length-1) { return; } stringps=url.Substring(questionMarkIndex+1); //开始分析参数对 Regexre=newRegex(@"(^|&)?(\w+)=([^&]+)(&|$)?",RegexOptions.Compiled); MatchCollectionmc=re.Matches(ps); foreach(Matchminmc) { nvc.Add(m.Result("$2").ToLower(),m.Result("$3")); } } /// ///系统编号 /// publicstringSystemCode { get { returnRequest["systemCode"]??"Base"; } } //////权限编号 /// publicstringPermissionCode { get { returnRequest["permissionCode"]; } } //////访问接口的应用传来AppKey /// publicstringAppKey { get { returnRequest["appKey"]; } } //////访问接口的应用传来AppSecret /// publicstringAppSecret { get { returnRequest["appSecret"]; } } privateBaseUserInfo_userInfo=null; //////获取当前用户 ///通过接口AppKey和AppSecret获取的用户 /// ///publicBaseUserInfoUserInfo { get { BaseUserInfouserInfo=null; BaseUserEntityuserEntity=BaseUserManager.GetObjectByCodeByCache(AppKey); if(userEntity!=null) { if(BaseServicesLicenseManager.CheckServiceByCache(userEntity.Id,AppSecret)) { userInfo=newBaseUserInfo(); userInfo.Id=userEntity.Id; userInfo.RealName=userEntity.RealName; userInfo.UserName=userEntity.UserName; userInfo.IPAddress=Utilities.GetIPAddress(true); } } returnuserInfo; } } #region业务库连接 /// ///业务库连接 /// publicstaticIDbHelperBusinessDbHelper { get { returnDbHelperFactory.GetHelper(BaseSystemInfo.BusinessDbType,BaseSystemInfo.BusinessDbConnection); } } #endregion #region用户中心库连接 //////用户中心库连接 /// publicstaticIDbHelperUserCenterDbHelper { get { returnDbHelperFactory.GetHelper(BaseSystemInfo.UserCenterDbType,BaseSystemInfo.UserCenterDbConnection); } } #endregion }
7、统一回传格式实体
//////ApiResultModel ///统一回传格式实体 /// ///修改纪录 /// ///2016-10-31版本:1.0宋彪创建文件。 /// /// publicclassApiResultModel { publicHttpStatusCodeStatus{get;set;} //publicJsonResult/// ///宋彪 ///2016-10-31 ///Data{get;set;} publicobjectData{get;set;} publicstringErrorMessage{get;set;} }
8、留言相关接口
//////MessageBookController ///留言相关接口 /// ///修改纪录 /// ///2016-10-31版本:1.0宋彪创建文件。 /// /// [ApiAuthFilter] publicclassCustomerMessageController:ApiController { ////// ///宋彪 ///2016-10-31 //////保存单号留言信息 /// ////// [HttpPost] //[AllowAnonymous]不需要验证的就加这个标签 publicIHttpActionResultAdd([FromBody]MsgbookCusEntitymessageBook) { BaseResultbaseResult=newBaseResult(); if(string.IsNullOrWhiteSpace(messageBook.SystemFrom)) { baseResult.Status=false; baseResult.StatusMessage="SystemFrom参数不可为空"; } else { try { MsgbookCusManagermanager=newMsgbookCusManager(APIOperateContext.BusinessDbHelper,APIOperateContext.Current.UserInfo); MsgbookCusEntitymodel=newMsgbookCusEntity(); 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=0; manager.Add(model,false,false); baseResult.Status=true; baseResult.StatusMessage="添加成功。"; } catch(Exceptionex) { NLogHelper.Warn(ex,"CustomerMessageControllerAddBillMessage异常"); baseResult.Status=false; baseResult.StatusMessage="异常:"+ex.Message; } } returnOk(baseResult); } /// ///获取某个单号的留言 /// ////// [HttpGet] publicIHttpActionResultGetList(stringbillCode) { JsonResult >jsonResult=newJsonResult
>(); try { MsgbookCusManagermanager=newMsgbookCusManager(APIOperateContext.BusinessDbHelper,APIOperateContext.Current.UserInfo); List
list=newList (); list=manager.GetList (newKeyValuePair (MsgbookCusEntity.FieldBillCode,billCode) ,newKeyValuePair (MsgbookCusEntity.FieldDeletionStateCode,0)); jsonResult.Status=true; jsonResult.RecordCount=list.Count; jsonResult.Data=list; jsonResult.StatusMessage="获取成功"; } catch(Exceptionex) { NLogHelper.Warn(ex,"CustomerMessageControllerAddBillMessage异常"); jsonResult.Status=false; jsonResult.StatusMessage="异常:"+ex.Message; } returnOk(jsonResult); } }
9、接口调用方法
//////测试留言接口调用 /// ///publicActionResultAddCustomerMessage() { stringurl="http://192.168.1.88:808/api/CustomerMessage/Add?"; WebClientwebClient=newWebClient(); NameValueCollectionpostValues=newNameValueCollection(); postValues.Add("Message","填写您的留言内容吧"); postValues.Add("SendEmail","youemail@qq.com"); postValues.Add("SendTelephone","021-60375335"); postValues.Add("Code","661137858"); postValues.Add("AppKey","wssavbcn"); postValues.Add("AppSecret","350e66b1e6564b0a817163erwwwwe8"); postValues.Add("SystemFrom","官网"); byte[]responseArray=webClient.UploadValues(url,postValues); stringresponse=Encoding.UTF8.GetString(responseArray); returnContent(response); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。