【C#】入力チェックを実装する
前提
- Vsual Studio 2017がインストールされていること
本記事でやること
ModelState.IsValidでModelを検証する
Modelを作成する
まず下記のようなModel[UserInfo]を作成します。C#
public class UserInfo { public string id { get; set; } public string password { get; set; } public string name { get; set; } public string mailAddress { get; set; } public IList<Skill> skillList { get; set; } } public class Skill { public string skillName { get; set; } public string experience { get; set; } }
属性を付ける
次に各項目に属性をつけます。この項目は「半角英数字のみ許可する」とか「必須項目とする」とか。
下記を参考に属性を付けてみました。
qiita.com
C#
public class UserInfo { [DisplayName("ID")] [Required(ErrorMessage = "IDは必須です")] public string Id { get; set; } [DisplayName("パスワード")] [Required(ErrorMessage = "パスワードは必須です")] public string Password { get; set; } [DisplayName("名前")] [Required(ErrorMessage = "名前は必須です")] public string Name { get; set; } [DisplayName("メールアドレス")] [EmailAddress(ErrorMessage = "メールアドレスの形式で入力してください")] [Required(ErrorMessage = "メールアドレスは必須です")] public string MailAddress { get; set; } [DisplayName("スキルリスト")] public IList<Skill> SkillList { get; set; } } public class Skill { [DisplayName("スキル名")] [Required(ErrorMessage = "スキル名は必須です")] public string SkillName { get; set; } [DisplayName("経験年数")] [Required(ErrorMessage = "経験年数は必須です")] [MaxLength(3)] [MinLength(1)] [RegularExpression(@"[0-9]+", ErrorMessage = "半角数字のみ入力できます")] public string Experience { get; set; } }
Modelを検証する
Modelの検証には、ModelState.IsValidメソッドを使用します。こんな感じに。
C#
public IHttpActionResult Post([FromBody]UserInfo reqParam) { string RESULT_OK = "0"; string RESULT_NG = "1"; ResultInfo result = new ResultInfo(); result.result = RESULT_OK; // リクエストパラメータを検証 if (!ModelState.IsValid) { result.result = RESULT_NG; return Json(result); } return Json(result); }
リクエストパラメータの「Id」を空にしてリクエストを送ってみます↓
IDは必須なので、RESULT_NG("result" : "1")で返却されました。
このままでもエラーなのは分かりますが、
どんなエラー内容なのかがクライアントに伝わりません。
クライアントがどんなエラーなのか分かりやすくするために、
適当なエラーメッセージを返してあげます。
エラーメッセージを作成する
エラー情報用Modelを作成する
以下のようにエラー情報用のModelと処理結果用のModelを作成しました。C#
public class ResultInfo { public string result { get; set; } public IList<ErrorInfo> errorInfoList { get; set; } = new List<ErrorInfo>(); } public class ErrorInfo { public string errorId { get; set; } public string errorMessage { get; set; } }
エラーメッセージを作成する
リクエストパラメータ内のエラー項目の値を取得し、クライアントへ返却するエラーメッセージを作成します。
※Controllerにこういった処理を書くのは適切ではないと思いますが、
検証のため一旦ここに書いてあります。
「入力値チェックってここに書くといいと思うよ!」っていうのがあれば、
コメントいただけると嬉しいです!
C#
public IHttpActionResult Post([FromBody]UserInfo reqParam) { // 処理結果(初期値としてOKを設定) ResultInfo result = new ResultInfo(); result.result = RESULT_OK; // 入力値エラーがあった場合 if (!ModelState.IsValid) { foreach (string key in ModelState.Keys) { if (ModelState[key].Errors.Count > 0) { string[] keys = key.Split('.'); object value = reqParam; string inputKey = ""; string inputValue = ""; for (int i = 1; i < keys.Length; ++i) { // エラーがあった項目の値を取得する value = getValue(value, keys[i]); inputValue = (value == null ? "" : value.ToString()); inputKey = keys[i]; } foreach (ModelError modelErr in ModelState[key].Errors) { // エラーメッセージを作成 string message = modelErr.ErrorMessage; ErrorInfo errorInfo = new ErrorInfo(); errorInfo.errorId = "E001"; errorInfo.errorMessage = modelErr.ErrorMessage + " 入力値:「" + inputValue + "」"; result.errorInfoList.Add(errorInfo); } } } return Json(result); } return Json(result); }
↑のControllerの中で使うメソッド「getValue()」
入力値取得用のメソッドを作成しました。正規表現でList型か判定し、キー項目に対応する値を取得します。
C#
/// <summary> /// オブジェクト内から指定されたKEYに対応したVALUEを取得する。 /// </summary> /// <param name="obj">オブジェクト</param> /// <param name="key">キー</param> static public object getValue(object obj, string key) { // オブジェクトの型を取得 Type type = obj.GetType(); // key項目がListか判定 Match matche = Regex.Match(key, "^(.*?)\\[(\\d)\\]"); if (matche.Success) { // Listの場合 PropertyInfo property = type.GetProperty(matche.Groups[1].Value); IList list = property.GetValue(obj, null) as IList; return list[int.Parse(matche.Groups[2].Value)]; } else { // Listでない場合 PropertyInfo property = type.GetProperty(key); return property.GetValue(obj, null); } }
動作確認
以下の画像の通りリクエストパラメータを設定し、リクエストを投げます。
想定したエラーメッセージが出力されました。