WebApi資料驗證——ModelState驗證返回所有錯誤資訊,並統一返回公共結果類,
阿新 • • 發佈:2019-05-03
一. 公共返回類(根據專案需要來定義,與正常請求資料返回結果類一致)
注:泛型的返回類請自己擴充,本文只為示例,只列舉一個非泛型的返回類。
EnumAppCode 為錯誤碼的列舉,請自行定義。
using OF.Utility; namespace Certification.Api.Common { /// <summary> /// 統一返回結果,用於不需要返回具體結果實體的方法呼叫中,即只包含status和message兩個屬性,請不要擅自修改改類的任何地方 /// </summary> public class ResultData { private ResultData() { } /// <summary> /// 返回狀態 /// 0:成功,否則失敗 /// </summary> public int status { set; get; } /// <summary> /// 錯誤資訊 /// </summary> public string message { set; get; } /// <summary> /// /// </summary> /// <returns></returns> public static ResultData Success() { ResultData result = new ResultData { status = 0, message = "", }; return result; } /// <summary> /// /// </summary> /// <param name="msg"></param> /// <returns></returns> public static ResultData Success(string msg) { ResultData result = new ResultData { status = 0, message = msg, }; return result; } public static ResultData Error() { return Error(EnumAppCode.RequestError); } /// <summary> /// /// </summary> /// <param name="errorCode"></param> /// <returns></returns> public static ResultData Error(EnumAppCode errorCode) { ResultData result = new ResultData { status = (int)errorCode, message = errorCode.GetEnumText() }; return result; } /// <summary> /// /// </summary> /// <param name="errorCode"></param> /// <param name="errMsg"></param> /// <returns></returns> public static ResultData Error(EnumAppCode errorCode,string errMsg) { ResultData result = new ResultData { status = (int)errorCode, message = errMsg }; return result; } } }
二. 編寫ModelState擴充套件方法,拼接ModelState錯誤資訊
using System; using System.Collections.Generic; using System.Linq; using System.Web.Http.ModelBinding; namespace Certification.Api.Common { /// <summary> /// ModelState擴充套件類 /// </summary> public static class ModelStateExtension { /// <summary> /// 獲取模型繫結中的第一條錯誤資訊 /// </summary> /// <param name="msDictionary"></param> /// <returns></returns> public static string GetFirstErrMsg(this ModelStateDictionary msDictionary) { if (msDictionary.IsValid || !msDictionary.Any()) return ""; foreach (string key in msDictionary.Keys) { ModelState tempModelState = msDictionary[key]; if (tempModelState.Errors.Any()) { var firstOrDefault = tempModelState.Errors.FirstOrDefault(); if (firstOrDefault != null) return firstOrDefault.ErrorMessage; } } return ""; } /// <summary> /// 獲取錯誤資訊列表 /// </summary> /// <param name="msDictionary"></param> /// <returns></returns> public static List<string> GetErrMsgList(this ModelStateDictionary msDictionary) { var list = new List<string>(); if (msDictionary.IsValid || !msDictionary.Any()) return list; //獲取所有錯誤的Key foreach (string key in msDictionary.Keys) { ModelState tempModelState = msDictionary[key]; if (tempModelState.Errors.Any()) { var errorList = tempModelState.Errors.ToList(); foreach (var item in errorList) { list.Add(item.ErrorMessage); } } } return list; } /// <summary> /// 獲取ModelState所有錯誤資訊,間隔符間隔 /// </summary> /// <param name="splitStr">間隔符</param> /// <returns></returns> public static string GetAllErrMsgStr(this ModelStateDictionary msDictionary, string splitStr) { var returnStr = ""; if (msDictionary.IsValid || !msDictionary.Any()) return returnStr; //獲取所有錯誤的Key foreach (string key in msDictionary.Keys) { ModelState tempModelState = msDictionary[key]; if (tempModelState.Errors.Any()) { var errorList = tempModelState.Errors.ToList(); foreach (var item in errorList) { returnStr += item.ErrorMessage + splitStr; } } } return returnStr; } } }
三. 編寫Filter過濾器,新增WebApi全域性驗證
可以配合上篇文章《WebApi資料驗證——編寫自定義資料註解(Data Annotations)》使用,
利用自定義註解定義驗證規則和錯誤資訊,API專案Filter全域性統一攔截驗證丟擲自定義的錯誤資訊。
using Certification.Api.Common;
using Newtonsoft.Json;
using System.Net.Http;
using System.Text;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace Certification.Api.Filters
{
public class GlobalActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ModelState.IsValid == false)
{
var result = ResultData.Error(EnumAppCode.InternalServer);
result.message = actionContext.ModelState.GetAllErrMsgStr(",");
actionContext.Response = new HttpResponseMessage { Content = new StringContent(JsonConvert.SerializeObject(result), Encoding.GetEncoding("UTF-8"), "application/json") };
}
}
}
}