Web Api在Int或DateTime如果傳空值的話會自動幫忙設預設值,但是在ModelState.IsValid的時候,卻會出現型別上的錯誤.
解決方式
把Model改成正確,也就是預設允許可以為null
public?class?DemoModel??????????????????????????????{???????????????????????????????????????????????????public?int??Id?{?get;?set;?}????????????????????[Required]??????????????????????????????????????public?string?Name?{?get;?set;?}????????????????public?DateTime??SelectedDate?{?get;?set;?}?????}
但是這種解決方式卻不能解決我的問題,更多這類情境其實還蠻容易發生在web form轉到mvc或web api的時候,因為當你想要翻舊系統的時候,會想要把驗證集中放在Model上面,不過即有好幾仟個類別可能都已定型,甚至有些是還透過map或者直接對應db的狀況,我們不可能去抓出所有會發生錯誤的狀況,一一的去排除掉啊,那我的想法是否能只驗證我有定義的attribute,而忽略掉型別的檢查呢?如果int或datetime給空值的話,也不會出錯呢?其實這個解法是筆者自己寫出來的,google也都沒有相關的解法,可能是普遍大家都不會這樣子干,但是在筆者目前的情境卻不得不這樣做,所以是否要這樣子做就視各位的情境了。
public?class?ValidateModelAttribute?:?ActionFilterAttribute{public?override?void?OnActionExecuting(HttpActionContext?actionContext){if?(actionContext.ActionDescriptor.GetCustomAttributes<IgnoreValidateModelAttribute>(false).Any()){return;}var?httpMethod?=?actionContext.Request.Method;????????????if?(httpMethod?==?HttpMethod.Get?||?httpMethod?==?HttpMethod.Options){return;}var?modelResult?=?new?ModelStateDictionary();foreach?(var?item?in?actionContext.ModelState){var?errors?=?item.Value.Errors.FirstOrDefault();var?hasException?=?item.Value.Errors.Any(x?=>?x.Exception?!=?null);if?(hasException){continue;}modelResult.AddModelError(item.Key,?errors.ErrorMessage);?//自行新增只有ErrorMessage的部份,而忽略型別轉換的錯誤提示}if?(modelResult.Count?>?0){actionContext.Response?=?actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest,?modelResult);}base.OnActionExecuting(actionContext);}}
以上述做法可以忽略有expection的錯誤提醒,但如果有expection的話那model error就會失效了,因為只要有任何expection的狀況,就會中止這個屬性的檢查,不會再加入任何error,也就是說如果我們設定為required,并且屬性也沒有給nullable的話,而且client端傳來又沒有給值的話,結果我們的model驗證卻沒有回應此欄位必須填值,就會變得非常怪異。