WebApi data validation - model state validation returns all error information, and returns common result classes uniformly,

Keywords: JSON encoding

I. public return class (defined according to the needs of the project, consistent with the normal request data return result class)

Note: please expand the generic return class yourself. This article is only an example and only lists one non generic return class.

EnumAppCode is an enumeration of error codes. Please define it yourself.


using OF.Utility;

namespace Certification.Api.Common
{
    /// <summary>
    ///Unified return results are used in method calls that do not need to return specific result entities, that is, only two properties, status and message, are included. Please do not modify any part of the class without permission 
    /// </summary>
    public class ResultData
    {
        private ResultData()
        {
            
        }
        /// <summary>
        ///Return to status
        ///0: success, otherwise failure
        /// </summary>
        public int status { set; get; }
      
        /// <summary>
        ///Error message
        /// </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;
        }
    }

    

}

II. Write the extension method of ModelState and splice the error information of ModelState

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.ModelBinding;

namespace Certification.Api.Common
{
    /// <summary>
    ///ModelState extension class
    /// </summary>
    public static class ModelStateExtension
    {
        /// <summary>
        ///Get the first error message in the model binding
        /// </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>
        ///Get error information list
        /// </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;

            //Get all wrong keys
            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>
        ///Get all error information of ModelState, interval
        /// </summary>
        ///< param name = "splitstr" > spacer < / param >
        /// <returns></returns>
        public static string GetAllErrMsgStr(this ModelStateDictionary msDictionary, string splitStr)
        {
            var returnStr = "";
            if (msDictionary.IsValid || !msDictionary.Any()) return returnStr;

            //Get all wrong keys
            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;
        }
    }
}

III. write Filter filter and add WebApi global verification

Can match the previous article WebApi data validation - writing custom Data Annotations Use,

The user-defined annotation is used to define the validation rules and error information, and the API project Filter globally intercepts the validation and throws the user-defined error information.

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

}

Posted by tron00 on Wed, 20 Nov 2019 07:03:14 -0800