栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > asp

ASP.NET MVC API 接口验证的示例代码

asp 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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
  /// 
  /// 
  ///    宋彪
  ///    2016.09.01
  ///  
  /// 
  public static class WebApiConfig
  {
    /// 
    /// 注册全局配置服务
    /// 
    /// 
    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;

  /// 
  /// ApiAuthFilterAttribute
  /// 身份验证过滤器,具有ApiAuthFilterAttribute标签属性的方法会自动检查
  /// 
  /// 
  /// 修改纪录
  /// 
  /// 2016-10-11 版本:1.0 SongBiao 创建文件。  
  /// 
  /// 
  ///   SongBiao
  ///   2016-10-11
  /// 
  /// 
  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
  public class ApiAuthFilterAttribute : AuthorizationFilterAttribute
  {
    /// 
    /// 未授权时的提示信息
    /// 
    private const string UnauthorizedMessage = "请求未授权,拒绝访问。";

    /// 
    /// 权限进入
    /// 
    /// 
    public override void onAuthorization(HttpActionContext actionContext)
    {
      base.onAuthorization(actionContext);
      // 允许匿名访问
      if (actionContext.ActionDescriptor.GetCustomAttributes().Count > 0) 
      {
 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("

Unauthorized

", 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, 0, 0, systemCode, permissionCode); if (!result.Status) { var response = actionContext.Response = actionContext.Response?? new HttpResponseMessage(); response.Content = new StringContent(result.ToJson(), Encoding.UTF8, "application/json"); } } } }

3、统一回传格式

  /// 
  /// ApiResultAttribute
  /// 统一回传格式
  /// 
  /// 修改纪录
  /// 
  /// 2016-10-31 版本:1.0 宋彪 创建文件。
  /// 
  /// 
  ///   宋彪
  ///   2016-10-31
  /// 
  /// 
  public class ApiResultAttribute : ActionFilterAttribute
  {
    /// 
    /// 重写回传的处理
    /// 
    /// 
    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().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;

  /// 
  /// ApiErrorHandleAttribute
  /// 全局异常处理
  /// 
  /// 修改纪录
  /// 
  /// 2016-10-31 版本:1.0 宋彪 创建文件。
  /// 
  /// 
  ///   宋彪
  ///   2016-10-31
  /// 
  /// 

  public class ApiErrorHandleAttribute : System.Web.Http.Filters.ExceptionFilterAttribute
  {
    /// 
    /// 异常统一处理
    /// 
    /// 
    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;

  /// 
  /// APIOperateContext
  /// 接口操作的上下文
  /// 跟上下文有关的一些通用的东西放在这里处理
  /// 
  /// 修改纪录
  /// 
  /// 2016-10-31 版本:1.0 宋彪 创建文件。
  /// 
  /// 
  ///   宋彪
  ///   2016-10-31
  /// 
  /// 
  public class APIOperateContext
  {
    /// 
    /// 获取当前 操作上下文 (为每个处理浏览器请求的服务器线程 单独创建 操作上下文)
    /// 
    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上下文 及 相关属性
    /// 
    /// Http上下文
    /// 
    public HttpContext ContextHttp
    {
      get
      {
 return HttpContext.Current;
      }
    }

    /// 
    /// 输出对象
    /// 
    public HttpResponse Response
    {
      get
      {
 return ContextHttp.Response;
      }
    }

    /// 
    /// 请求对象
    /// 
    public HttpRequest Request
    {
      get
      {
 return ContextHttp.Request;
      }
    }

    /// 
    /// Session对象
    /// 
    System.Web.SessionState.HttpSessionState Session
    {
      get
      {
 return ContextHttp.Session;
      }
    }
    #endregion

    /// 
    /// 获取全部请求参数,get和post的 简化版
    /// 
    public static string GetRequestParameters()
    {
      string query = HttpContext.Current.Request.Url.Query;
      NamevalueCollection nvc;
      string baseUrl;
      ParseUrl(query, out baseUrl, out nvc);
      List list = new List() { };
      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;
    }

    /// 
    /// 分析 url 字符串中的参数信息
    /// 针对get请求的
    /// 
    /// 输入的 URL
    /// 输出 URL 的基础部分
    /// 输出分析后得到的 (参数名,参数值) 的集合
    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 == -1)
      {
 baseUrl = url;
 return;
      }
      baseUrl = url.Substring(0, questionMarkIndex);
      if (questionMarkIndex == url.Length - 1)
      {
 return;
      }
      string ps = url.Substring(questionMarkIndex + 1);
      // 开始分析参数对 
      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"));
      }
    }

    /// 
    /// 系统编号
    /// 
    public string SystemCode
    {
      get
      {
 return Request["systemCode"] ?? "base";
      }
    }

    /// 
    /// 权限编号
    /// 
    public string PermissionCode
    {
      get
      {
 return Request["permissionCode"];
      }
    }

    /// 
    /// 访问接口的应用传来AppKey
    /// 
    public string AppKey
    {
      get
      {
 return Request["appKey"];
      }
    }

    /// 
    /// 访问接口的应用传来AppSecret
    /// 
    public string AppSecret
    {
      get
      {
 return Request["appSecret"];
      }
    }

    private baseUserInfo _userInfo = null;
    /// 
    /// 获取当前用户
    /// 通过接口AppKey和AppSecret获取的用户
    /// 
    /// 
    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 业务库连接
    /// 
    /// 业务库连接
    /// 
    public static IDbHelper BusinessDbHelper
    {
      get
      {
 return DbHelperFactory.GetHelper(baseSystemInfo.BusinessDbType, baseSystemInfo.BusinessDbConnection);
      }
    }
    #endregion

    #region 用户中心库连接
    /// 
    /// 用户中心库连接
    /// 
    public static IDbHelper UserCenterDbHelper
    {
      get
      {
 return DbHelperFactory.GetHelper(baseSystemInfo.UserCenterDbType, baseSystemInfo.UserCenterDbConnection);
      }
    }
    #endregion


  }

7、统一回传格式实体

  /// 
  /// ApiResultModel
  /// 统一回传格式实体
  /// 
  /// 修改纪录
  /// 
  /// 2016-10-31 版本:1.0 宋彪 创建文件。
  /// 
  /// 
  ///   宋彪
  ///   2016-10-31
  /// 
  /// 
  public class ApiResultModel
  {
    public HttpStatusCode Status { get; set; }

    //public JsonResult Data { get; set; }
    public object Data { get; set; }
    public string ErrorMessage { get; set; }
  }

8、留言相关接口

  /// 
  /// MessageBookController
  /// 留言相关接口
  /// 
  /// 修改纪录
  /// 
  /// 2016-10-31 版本:1.0 宋彪 创建文件。
  /// 
  /// 
  ///   宋彪
  ///   2016-10-31
  /// 
  /// 
  [ApiAuthFilter]
  public class CustomerMessageController : ApiController
  {
    /// 
    /// 保存单号留言信息
    /// 
    /// 
    /// 
    [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 = 0;
   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);
    }

    /// 
    /// 获取某个单号的留言
    /// 
    /// 
    /// 
    [HttpGet]
    public IHttpActionResult GetList(string billCode)
    {
      JsonResult> jsonResult = new JsonResult>();
      try
      {
 MsgbookCusManager manager = new MsgbookCusManager(APIOperateContext.BusinessDbHelper, APIOperateContext.Current.UserInfo);
 List list = new List();
 list = manager.GetList(new KeyValuePair(MsgbookCusEntity.FieldBillCode, billCode)
 , new KeyValuePair(MsgbookCusEntity.FieldDeletionStateCode, 0));

 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、接口调用方法

    /// 
    /// 测试留言接口调用
    /// 
    /// 
    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", "661137858");
      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);
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号