c#中WebApi开发遇到的坑
一、如何新建一个webApi项目
打开VS→找到解决方案→新建项目→类库或web应用程序→选择空的WebApi项目→在Global.asax文件的Application_Start方法中注册WebApi的相关配置→完成
二、如何对外提供api接口
在webApi项目的Controllers文件夹下新增一个类继承ApiController,在该类中就可以完成对外接口(GET、POST、PUT、DELETE等),需要注意的是如果提供的方法需要参数,则参数的类型不能按它实际的类型声明和传递,如Name不能直接声明为string类型,否则调用该接口时会报404错误,找不到该访问地址。声明的方式有很多种:
(1)创建一个类,该类只包含该方法所需的参数。
(2)引用FormDataCollection类来声明和接收参数。
这是常用的声明方式,推荐方法(2)。下面用例子的形式说明错误写法和正确写法
1 #region 参数声明示例·错误写法 2 [Route("Example")] 3 [HttpPost] 4 public object Example(string name) 5 { 6 var response = new ResponseModel 7 { 8 StatusCode = 200, 9 Message = "接收数据成功!", 10 Data = name 11 }; 12 return Json(response); 13 } 14 #endregion
1 #region 参数声明示例·正确写法 2 [Route("Example")] 3 [HttpPost] 4 public object Example(FormDataCollection collection) 5 { 6 var name = collection.Get("name"); 7 var response = new ResponseModel 8 { 9 StatusCode = 200, 10 Message = "接收数据成功!", 11 Data = name 12 }; 13 return Json(response); 14 } 15 #endregion
1 #region 参数声明示例·正确写法 2 [Route("Example")] 3 [HttpPost] 4 public object Example(DataInfo data) 5 { 6 var response = new ResponseModel 7 { 8 StatusCode = 200, 9 Message = "接收数据成功!", 10 Data = data.Name 11 }; 12 return Json(response); 13 } 14 #endregion 15 16 public class DataInfo 17 { 18 public string Name { get; set; } 19 }
三、自定义票据验证筛选器
(1)创建类 AuthorFilter 继承 AuthorizeAttribute
1 using System; 2 using System.Configuration; 3 using System.Web; 4 using System.Web.Http; 5 using System.Web.Http.Controllers; 6 using System.Web.Security; 7 using Xryang.Core.Config; 8 9 namespace Xryang.Api.Author 10 { 11 public class AuthorFilter : AuthorizeAttribute 12 { 13 public override void OnAuthorization(HttpActionContext actionContext) 14 { 15 #region 验证token → 请求数据 16 var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase; 17 var token = content.Request.Headers["Secret"]; 18 if (!string.IsNullOrEmpty(token)) 19 { 20 //验证token 21 if (ValidateTicket(token)) 22 { 23 base.IsAuthorized(actionContext); 24 } 25 else 26 { 27 HandleUnauthorizedRequest(actionContext); 28 } 29 return; 30 } 31 #endregion 32 33 #region 请求token 34 var appId = content.Request.Headers["AppId"]; 35 if (!string.IsNullOrEmpty(appId)) 36 { 37 //验证AppId 38 if (IsAllowAppId(appId)) 39 { 40 base.IsAuthorized(actionContext); 41 } 42 else 43 { 44 HandleUnauthorizedRequest(actionContext); 45 } 46 return; 47 } 48 #endregion 49 50 #region 非法请求 51 HandleUnauthorizedRequest(actionContext); 52 #endregion 53 } 54 55 #region 验证Token 56 //校验票据(数据库数据匹配) 57 private bool ValidateTicket(string token) 58 { 59 bool flag = false; 60 try 61 { 62 //解密Token 63 var ticket = FormsAuthentication.Decrypt(token).UserData; 64 if (ticket.Equals("token示例")) 65 flag = true; 66 } 67 catch (Exception ex) 68 { 69 70 } 71 return flag; 72 } 73 #endregion 74 75 #region 验证AppId 76 private bool IsAllowAppId(string appId) 77 { 78 var config = ConfigurationManager.GetSection("XryangConfig") as XryangConfig; 79 if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(config.AppId)) return false; 80 if (appId.Equals(config.AppId)) return true; 81 return false; 82 } 83 #endregion 84 } 85 }
(2)在api控制器或方法上加上 [AuthorFilter] 即可
1 using System; 2 using System.Net.Http.Formatting; 3 using System.Web.Http; 4 using System.Web.Security; 5 using Xryang.Api.Author; 6 using Xryang.Model.Commons; 7 8 namespace Xryang.Api.Controllers 9 { 10 [AuthorFilter] 11 [RoutePrefix("Api/App")] 12 public class AppController : ApiController 13 { 14 15 #region 获取token 16 [Route("Token")] 17 [HttpPost] 18 public object Token() 19 { 20 var response = new ResponseModel 21 { 22 StatusCode = 500, 23 Message = "很抱歉,系统出错了", 24 }; 25 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(0, "token示例", DateTime.Now, 26 DateTime.Now.AddHours(1), true, "token示例", 27 FormsAuthentication.FormsCookiePath); 28 if (ticket != null) 29 { 30 var token = FormsAuthentication.Encrypt(ticket); 31 response.StatusCode = 200; 32 response.Message = "获取成功"; 33 response.Data = new { Secret = token }; 34 } 35 return Json(response); 36 } 37 #endregion 38 39 #region 参数声明示例·正确写法 40 [Route("Example")] 41 [HttpPost] 42 public object Example(FormDataCollection data) 43 { 44 var response = new ResponseModel 45 { 46 StatusCode = 200, 47 Message = "接收数据成功!", 48 Data = data.Get("Name") 49 }; 50 return Json(response); 51 } 52 #endregion 53 } 54 }