モデルでアノテーション(Required)を指定しているプロパティが4つあります。
[Required] public string A { get; set; } [Required] public string B { get; set; } [Required] public string C { get; set; } [Required] public string D { get; set; }
条件によってこのアノテーションを無効にしたり有効にしたりする方法はありますでしょうか?(Dだけは必ず有効)
FLGというプロパティがあるとして、その値が1の時はRequiredを有効0の時は無効みたいな事が出来ればいいと思っています。
カスタムバリデーションなどで下記のようなことも考えましたが、「m.A」の所をABCすべてに対応させる方法がわかりませんでした。
public static ValidationResult CheckRequired(Test m) { if (m.FLG=="1" && m.A == null) { return new ValidationResult("エラー"); } return ValidationResult.Success; }
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
下記のような質問は推奨されていません。
- 質問になっていない投稿
- スパムや攻撃的な表現を用いた投稿
適切な質問に修正を依頼しましょう。
2017/06/14 13:20
2017/06/15 03:19
回答2件
1
条件付きの必須ということは、その条件のロジックを実装する必要があります。
つまりアノテーション1行では表現できないはずです。
従って、モデルにIValidatableObjectインターフェイスを実装してValidateメソッドで行うのが普通ではないでしょうか。
質問者様の追記を見て下記仕様と想定し、ソースコードを記載します。
- FLGのチェックボックスがONのときのみテキストボックスA、B、Cの必須チェックを行う
- チェックボックスがOFFの時はABCは非活性
- Dだけは常に必須チェックを行う
C#
1[Serializable] 2public class TestModel : IValidatableObject 3{ 4 public string Flg { get; set; } 5 public string A { get; set; } 6 public string B { get; set; } 7 public string C { get; set; } 8 [Required] 9 public string D { get; set; } 10 11 public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 12 { 13 if (this.Flg == "1") 14 { 15 if (string.IsNullOrEmpty(this.A)) 16 { 17 yield return new ValidationResult("Aは入力が必須です。", new string[] { "A" }); 18 } 19 if (string.IsNullOrEmpty(this.B)) 20 { 21 yield return new ValidationResult("Bは入力が必須です。", new string[] { "B" }); 22 } 23 if (string.IsNullOrEmpty(this.C)) 24 { 25 yield return new ValidationResult("Cは入力が必須です。", new string[] { "C" }); 26 } 27 } 28 } 29}
投稿2017/06/15 00:47
編集2017/06/15 23:49総合スコア557
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
2017/06/15 09:08
2017/06/15 11:39 編集
0
ベストアンサー
私のコメント(サーバー側だけの検証で OK か?)に返事がないですが、それで OK と勝手に理解して回答します。
質問者さんが考えたように CustomValidationAttribute を使うのが正解だと思います。
FLG プロパティも Model 定義に含めてテキストボックスの文字列と一緒に View から POST するようにすれば、検証メソッドの引数に FLG およびテキストボックス A ~ D のユーザー入力すべてがモデルバインドされますので、そこで検証できます。
具体的には以下のような感じです。
Controller と Model
Controller と Model を一緒にしたのは単に分けるのが面倒だったから。CustomValidation 属性は各プロパティではなくクラスに設定。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using AdventureWorksLT; using Mvc5App.Extensions; using System.ComponentModel.DataAnnotations; namespace Mvc5App.Controllers { [CustomValidation(typeof(SampleModel), "ValidateSampleModel")] public class SampleModel { public bool Flg { get; set; } public string A { get; set; } public string B { get; set; } public string C { get; set; } public string D { get; set; } public static ValidationResult ValidateSampleModel(SampleModel model) { if (model == null) { throw new NullReferenceException(); } if (model.Flg) { // 事前に Trim した方がよさそうだが省略 if (String.IsNullOrEmpty(model.A) || String.IsNullOrEmpty(model.B) || String.IsNullOrEmpty(model.C) || String.IsNullOrEmpty(model.D)) { return new ValidationResult("Flg = 1 and one or more of TextBox(es) A, B, C & D empty"); } } else { if (String.IsNullOrEmpty(model.D)) { return new ValidationResult("Flg = 0 and TextBox D empty"); } } return ValidationResult.Success; } } public class HomeController : Controller { public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(SampleModel sample) { if (!ModelState.IsValid) { return View(sample); } return RedirectToAction("Index", "Home"); } } }
View
エラーメッセージは ValidationSummary を利用して表示。
@model Mvc5App.Controllers.SampleModel @{ ViewBag.Title = "Create"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>Create</h2> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>SampleModel</legend> <div class="editor-label"> @Html.LabelFor(model => model.Flg) </div> <div class="editor-field"> @Html.EditorFor(model => model.Flg) </div> <div class="editor-label"> @Html.LabelFor(model => model.A) </div> <div class="editor-field"> @Html.EditorFor(model => model.A) </div> <div class="editor-label"> @Html.LabelFor(model => model.B) </div> <div class="editor-field"> @Html.EditorFor(model => model.B) </div> <div class="editor-label"> @Html.LabelFor(model => model.C) </div> <div class="editor-field"> @Html.EditorFor(model => model.C) </div> <div class="editor-label"> @Html.LabelFor(model => model.D) </div> <div class="editor-field"> @Html.EditorFor(model => model.D) </div> <p> <input type="submit" value="Create" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval", "~/bundles/inarray") }
投稿2017/06/15 09:05
総合スコア17909
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
関連した質問
Q&A
解決済
DefaultTableModelのremoveRow()メソッドに関して
回答2
クリップ1
更新
2023/05/21
Q&A
解決済
YahooApiを使ってキーワードをSystem.out.printlnでコンソールに提示したい
回答1
クリップ0
更新
2023/05/17
Q&A
受付中
java アルファベット順に並び替え
回答3
クリップ0
更新
2023/05/27
Q&A
解決済
関数の呼び出しについて
回答2
クリップ0
更新
2023/05/26
Q&A
解決済
Javaの外部ライブラリが使えない
回答1
クリップ0
更新
2023/05/30
Q&A
受付中
Atcoder ABC301 D Bitmaskが分かりません
回答1
クリップ0
更新
2023/05/31
Q&A
受付中
表計算(集計)機能を使い、データから最年長を表示したい
回答3
クリップ0
更新
2023/05/26
Q&A
解決済
Javaでの不具合となります。
回答1
クリップ0
更新
2023/05/29
同じタグがついた質問を見る
C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。
ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。