Sample code for ASP. NET MVC API interface validation
- 2021-10-15 10:21:19
- OfStack
There is a message interface in the project, which receives messages and displays messages from other systems. Referring to some API verification methods on the Internet, it is found that the verification method provided by the general authority management system is the most perfect.
The complete idea sharing that will be implemented below
1. WebApiConfig Global Processing
/// <summary>
/// WebApiConfig
/// Routing base configuration.
///
///
/// Modify record
///
/// 2016.11.01 Version: 2.0 Song Biao Unify the date format 1 Handle.
/// 2016.10.30 Version: 2.0 Song Biao Solve json Circular reference problem during serialization.
/// 2016.10.28 Version: 2.0 Song Biao Return response format $format Support.
/// 2016.09.01 Version: 1.0 Song Biao Create.
///
/// Version: 1.0
///
/// <author>
/// <name> Song Biao </name>
/// <date>2016.09.01</date>
/// </author>
/// </summary>
public static class WebApiConfig
{
/// <summary>
/// Register the Global Configuration Service
/// </summary>
/// <param name="config"></param>
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Mandatory https Visit
//config.Filters.Add(new ForceHttpsAttribute());
// Unified 1 Return format
config.Filters.Add(new ApiResultAttribute());
// Handling when an exception occurs
config.Filters.Add(new ApiErrorHandleAttribute());
// ToKen Authentication filter More convenient You don't need to be here anymore Those with changed labels will be automatically checked
//config.Filters.Add(new ApiAuthFilterAttribute());
// Solve json Circular reference problem during serialization
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
// Unify the date format 1 Deal with
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
new IsoDateTimeConverter()
{
DateTimeFormat = "yyyy-MM-dd hh:mm:ss"
}
);
// Web API routes Route
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Kill XML Serializer
//config.Formatters.Remove(config.Formatters.XmlFormatter);
// In the requested Url Plus ?$format=xml You can specify the response format
config.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml");
config.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json");
}
}
2. Authentication Filter
using DotNet.Business;
using DotNet.Utilities;
using DotNet.Tracking.API.Common;
/// <summary>
/// ApiAuthFilterAttribute
/// Authentication filter , Have ApiAuthFilterAttribute Label properties are automatically checked by the method
///
///
/// Record modification
///
/// 2016-10-11 Version: 1.0 SongBiao Create a file.
///
/// <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>
/// Prompt information when not authorized
/// </summary>
private const string UnauthorizedMessage = " Request unauthorized, access denied. ";
/// <summary>
/// Permission access
/// </summary>
/// <param name="actionContext"></param>
public override void OnAuthorization(HttpActionContext actionContext)
{
base.OnAuthorization(actionContext);
// Allow anonymous access
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))
{
// Unauthenticated (logged in) users , And non-anonymous access, go to the login page
//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
{
// Check AppKey And 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. Unified 1 return format
/// <summary>
/// ApiResultAttribute
/// Unified 1 Return format
///
/// Record modification
///
/// 2016-10-31 Version: 1.0 Song Biao Create a file.
///
/// <author>
/// <name> Song Biao </name>
/// <date>2016-10-31</date>
/// </author>
/// </summary>
public class ApiResultAttribute : ActionFilterAttribute
{
/// <summary>
/// Processing of rewrite return
/// </summary>
/// <param name="actionExecutedContext"></param>
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
// The express tracking interface transmits format You don't have to go here
if (actionExecutedContext.Request.Properties.ContainsKey("format"))
{
// If an exception occurs, it will not be handled here Handling in exceptions ApiErrorHandleAttribute
if (actionExecutedContext.Exception != null)
return;
base.OnActionExecuted(actionExecutedContext);
var result = new ApiResultModel();
// Obtain by API Status code returned
result.Status = actionExecutedContext.ActionContext.Response.StatusCode;
// Obtain by API Data returned
result.Data = actionExecutedContext.ActionContext.Response.Content.ReadAsAsync<object>().Result;
// Recapsulate the backhaul format
actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(result.Status, result);
}
}
}
4. Global exception handling
using DotNet.Utilities;
using DotNet.Tracking.API.Common;
using DotNet.Tracking.API.Controllers;
using DotNet.Tracking.API.Models;
/// <summary>
/// ApiErrorHandleAttribute
/// Global exception handling
///
/// Record modification
///
/// 2016-10-31 Version: 1.0 Song Biao Create a file.
///
/// <author>
/// <name> Song Biao </name>
/// <date>2016-10-31</date>
/// </author>
/// </summary>
public class ApiErrorHandleAttribute : System.Web.Http.Filters.ExceptionFilterAttribute
{
/// <summary>
/// Anomaly series 1 Deal with
/// </summary>
/// <param name="actionExecutedContext"></param>
public override void OnException(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
{
base.OnException(actionExecutedContext);
// Get the error message when an exception occurs
var errorMessage = actionExecutedContext.Exception.Message;
// Exception record
string parameters = APIOperateContext.GetRequestParameters();
NLogHelper.Trace(actionExecutedContext.Exception, BaseSystemInfo.SystemCode + " ApiErrorHandleAttribute OnException Complete request address and parameters : " + parameters);
// 2016-11-01 Add an exception mail reminder
NLogHelper.InfoMail(actionExecutedContext.Exception, BaseSystemInfo.SystemCode + " ApiErrorHandleAttribute OnException Complete request address and parameters : " + parameters);
var result = new ApiResultModel()
{
Status = HttpStatusCode.BadRequest,
ErrorMessage = errorMessage
};
// Repackage the returned message
actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(result.Status, result);
}
}
5. Context of interface operation
using DotNet.Business;
using DotNet.Model;
using DotNet.Utilities;
/// <summary>
/// APIOperateContext
/// Context of interface operation
/// Context-sensitive 1 Some general-purpose things are disposed of here
///
/// Record modification
///
/// 2016-10-31 Version: 1.0 Song Biao Create a file.
///
/// <author>
/// <name> Song Biao </name>
/// <date>2016-10-31</date>
/// </author>
/// </summary>
public class APIOperateContext
{
/// <summary>
/// Gets the current Operation context ( For each server thread that processes browser requests Create separately Operation context )
/// </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 Context And Related attributes
/// <summary>
/// Http Context
/// </summary>
public HttpContext ContextHttp
{
get
{
return HttpContext.Current;
}
}
/// <summary>
/// Output object
/// </summary>
public HttpResponse Response
{
get
{
return ContextHttp.Response;
}
}
/// <summary>
/// Request object
/// </summary>
public HttpRequest Request
{
get
{
return ContextHttp.Request;
}
}
/// <summary>
/// Session Object
/// </summary>
System.Web.SessionState.HttpSessionState Session
{
get
{
return ContextHttp.Session;
}
}
#endregion
/// <summary>
/// Gets all request parameters, get And post Adj. Simplified version
/// </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>
/// Analysis url Parameter information in string
/// Aim at get Requested
/// </summary>
/// <param name="url"> Input URL</param>
/// <param name="baseUrl"> Output URL The basic part of </param>
/// <param name="nvc"> Output obtained after analysis ( Parameter name , Parameter value ) Collection of </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);
// Start analyzing parameter pairs
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>
/// System number
/// </summary>
public string SystemCode
{
get
{
return Request["systemCode"] ?? "Base";
}
}
/// <summary>
/// Authority number
/// </summary>
public string PermissionCode
{
get
{
return Request["permissionCode"];
}
}
/// <summary>
/// The application of the access interface is transmitted AppKey
/// </summary>
public string AppKey
{
get
{
return Request["appKey"];
}
}
/// <summary>
/// The application of the access interface is transmitted AppSecret
/// </summary>
public string AppSecret
{
get
{
return Request["appSecret"];
}
}
private BaseUserInfo _userInfo = null;
/// <summary>
/// Get the current user
/// Through the interface AppKey And AppSecret Obtained user
/// </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 Business library connection
/// <summary>
/// Business library connection
/// </summary>
public static IDbHelper BusinessDbHelper
{
get
{
return DbHelperFactory.GetHelper(BaseSystemInfo.BusinessDbType, BaseSystemInfo.BusinessDbConnection);
}
}
#endregion
#region User Center Library Connection
/// <summary>
/// User Center Library Connection
/// </summary>
public static IDbHelper UserCenterDbHelper
{
get
{
return DbHelperFactory.GetHelper(BaseSystemInfo.UserCenterDbType, BaseSystemInfo.UserCenterDbConnection);
}
}
#endregion
}
7. Unified 1 Return Format Entity
/// <summary>
/// ApiResultModel
/// Unified 1 Return format entity
///
/// Record modification
///
/// 2016-10-31 Version: 1.0 Song Biao Create a file.
///
/// <author>
/// <name> Song Biao </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. Message related interface
/// <summary>
/// MessageBookController
/// Message related interface
///
/// Record modification
///
/// 2016-10-31 Version: 1.0 Song Biao Create a file.
///
/// <author>
/// <name> Song Biao </name>
/// <date>2016-10-31</date>
/// </author>
/// </summary>
[ApiAuthFilter]
public class CustomerMessageController : ApiController
{
/// <summary>
/// Save the message information of the order number
/// </summary>
/// <param name="messageBook"></param>
/// <returns></returns>
[HttpPost]
//[AllowAnonymous] Add this label if you don't need verification
public IHttpActionResult Add([FromBody]MsgbookCusEntity messageBook)
{
BaseResult baseResult = new BaseResult();
if (string.IsNullOrWhiteSpace(messageBook.SystemFrom))
{
baseResult.Status = false;
baseResult.StatusMessage = "SystemFrom Parameter cannot be null ";
}
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 = " Added successfully. ";
}
catch (Exception ex)
{
NLogHelper.Warn(ex, "CustomerMessageController AddBillMessage Anomaly ");
baseResult.Status = false;
baseResult.StatusMessage = " Exception: " + ex.Message;
}
}
return Ok(baseResult);
}
/// <summary>
/// Get a message with a single number
/// </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 = " Achieve success ";
}
catch (Exception ex)
{
NLogHelper.Warn(ex, "CustomerMessageController AddBillMessage Anomaly ");
jsonResult.Status = false;
jsonResult.StatusMessage = " Exception: " + ex.Message;
}
return Ok(jsonResult);
}
}
9. Interface call method
/// <summary>
/// Test message interface call
/// </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", " Fill in your 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", " Official website ");
byte[] responseArray = webClient.UploadValues(url, postValues);
string response = Encoding.UTF8.GetString(responseArray);
return Content(response);
}