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

2025-05-29 0 41

项目中有一个留言消息接口,接收其他系统的留言和展示留言,参考了网上的一些API验证方法,发现使用通用权限管理系统提供的验证方法最完美。

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

1、WebApiConfig全局处理

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63
/// <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、身份验证过滤器

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70
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 > 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("<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, 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、统一回传格式

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38
/// <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、全局异常处理

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46
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、接口操作的上下文

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247
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 == -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"));

}

}

/// <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、统一回传格式实体

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21
/// <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、留言相关接口

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92
/// <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 = 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);

}

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23
/// <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", "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);

}

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

原文链接:http://www.cnblogs.com/hnsongbiao/p/6025677.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 ASP.NET MVC API 接口验证的示例代码 https://www.kuaiidc.com/99706.html

相关文章

发表评论
暂无评论