1. 程式人生 > >WebApi資料驗證——ModelState驗證返回所有錯誤資訊,並統一返回公共結果類,

WebApi資料驗證——ModelState驗證返回所有錯誤資訊,並統一返回公共結果類,

一. 公共返回類(根據專案需要來定義,與正常請求資料返回結果類一致)

注:泛型的返回類請自己擴充,本文只為示例,只列舉一個非泛型的返回類。

     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") };
            }
        }
    }

}