質問するログイン新規登録

回答編集履歴

2

追記

2019/07/12 07:42

投稿

退会済みユーザー
answer CHANGED
@@ -2,4 +2,149 @@
2
2
 
3
3
  00 分 00 秒以上、59 分 59 秒以下という範囲を超えたらエラーを出すにはデータアノテーション属性(RegularExpression または Range)を付与することで可能です。
4
4
 
5
- あと、未検証ですが、00:mm:ss という形でテキストボックスに入力する必要がありそうです。
5
+ あと、未検証ですが、00:mm:ss という形でテキストボックスに入力する必要がありそうです。
6
+
7
+ **【追記】**
8
+
9
+ ちょっと検証してみました。
10
+
11
+ テキストボックスの表示は mm:ss としても、それを送信してサーバー側で受けるときは hh:mm と解釈されるのが問題です。
12
+
13
+ つまり、例えば、テキストボックスに 30:00 とか 59:59 とか mm:ss 形式であれば有効な数字を入力しても、サーバー側では hh:mm 形式と解釈され、30 とか 59 は hh としては不正なのでモデルバインディングできずエラーになります。
14
+
15
+ なので、TextBoxFor の第 2 引数に "{0:mm\:ss}" を設定するのは mm:ss 形式で表示するだけならいいかもしれませんが、その後ユーザーが編集して送信ということが必要なら、送信する前に 00:mm:ss にしなければならないということで、操作が面倒になるだけなので意味がなさそうです。
16
+
17
+ TextBoxFor の第 2 引数は "{0:hh\:mm\:ss}" と設定しで最初から hh:mm:ss 形式で表示し、00 分 00 秒以上、59 分 59 秒以下という範囲を超えたらエラーを出すにはデータアノテーション属性(RegularExpression または Range)を付与することで対応するのをお勧めします。
18
+
19
+ ご参考までに検証に使ったコードをアップしておきます。
20
+
21
+ **Model**
22
+
23
+ ```
24
+ using System;
25
+ using System.Collections.Generic;
26
+ using System.Linq;
27
+ using System.Web;
28
+ using System.ComponentModel.DataAnnotations;
29
+ using System.ComponentModel.DataAnnotations.Schema;
30
+ using System.Globalization;
31
+
32
+ namespace Mvc5App.Models
33
+ {
34
+ public class TimeSpanModel
35
+ {
36
+ [Required]
37
+ // クライアント側の検証を無効にすれば RangeAttribute でも可
38
+ //[Range(typeof(TimeSpan), "00:00:00", "00:59:59")]
39
+ [RegularExpression(@"^00:[0-5]\d:[0-5]\d$")]
40
+ public TimeSpan Start { set; get; }
41
+
42
+ [Required]
43
+ // クライアント側の検証を無効にすれば RangeAttribute でも可
44
+ //[Range(typeof(TimeSpan), "00:00:00", "00:59:59")]
45
+ [RegularExpression(@"^00:[0-5]\d:[0-5]\d$")]
46
+ public TimeSpan Stop { set; get; }
47
+ }
48
+ }
49
+ ```
50
+
51
+ **View**
52
+
53
+ ```
54
+ @model Mvc5App.Models.TimeSpanModel
55
+
56
+ @{
57
+ ViewBag.Title = "TimeSpanTest";
58
+ Layout = "~/Views/Shared/_Layout.cshtml";
59
+
60
+ // クライアント側での検証を無効にするには以下のコメントアウトを解除
61
+ //Html.EnableClientValidation(false);
62
+ }
63
+
64
+ <h2>TimeSpanTest</h2>
65
+
66
+ @using (Html.BeginForm())
67
+ {
68
+ @Html.AntiForgeryToken()
69
+
70
+ <div class="form-horizontal">
71
+ <h4>TimeSpanModel</h4>
72
+ <hr />
73
+ @Html.ValidationSummary(true, "", new { @class = "text-danger" })
74
+ <div class="form-group">
75
+ @Html.LabelFor(model => model.Start, htmlAttributes: new { @class = "control-label col-md-2" })
76
+ <div class="col-md-10">
77
+ @Html.TextBoxFor(model => model.Start, "{0:hh\:mm\:ss}", new { @class = "form-control" })
78
+ @Html.ValidationMessageFor(model => model.Start, "", new { @class = "text-danger" })
79
+ </div>
80
+ </div>
81
+
82
+ <div class="form-group">
83
+ @Html.LabelFor(model => model.Stop, htmlAttributes: new { @class = "control-label col-md-2" })
84
+ <div class="col-md-10">
85
+ @Html.TextBoxFor(model => model.Stop, "{0:hh\:mm\:ss}", new { @class = "form-control" })
86
+ @Html.ValidationMessageFor(model => model.Stop, "", new { @class = "text-danger" })
87
+ </div>
88
+ </div>
89
+
90
+ <div class="form-group">
91
+ <div class="col-md-offset-2 col-md-10">
92
+ <input type="submit" value="Create" class="btn btn-default" />
93
+ </div>
94
+ </div>
95
+ </div>
96
+ }
97
+
98
+ <div>
99
+ @Html.ActionLink("Back to List", "Index")
100
+ </div>
101
+
102
+ @section Scripts {
103
+ @Scripts.Render("~/bundles/jqueryval")
104
+ }
105
+ ```
106
+
107
+ **Controller**
108
+
109
+ ```
110
+ using System;
111
+ using System.Collections.Generic;
112
+ using System.Linq;
113
+ using System.Web;
114
+ using System.Web.Mvc;
115
+ using System.ComponentModel.DataAnnotations;
116
+ using Mvc5App.Models;
117
+ using System.IO;
118
+
119
+ namespace Mvc5App.Controllers
120
+ {
121
+ public class HomeController : Controller
122
+ {
123
+ public ActionResult TimeSpanTest()
124
+ {
125
+ TimeSpanModel model = new TimeSpanModel
126
+ {
127
+ Start = new TimeSpan(0, 0, 0),
128
+ Stop = new TimeSpan(0, 59, 59)
129
+ };
130
+
131
+ return View(model);
132
+ }
133
+
134
+ [HttpPost]
135
+ public ActionResult TimeSpanTest(TimeSpanModel model)
136
+ {
137
+ if (ModelState.IsValid)
138
+ {
139
+ return RedirectToAction("Index");
140
+ }
141
+
142
+ return View(model);
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ Model に付与した Rquired と RegularExpression での検証結果は以下のようになります。下の例ではエラーメッセージはデフォルトですが自由に設定できます。
149
+
150
+ ![イメージ説明](2fa57c405eeba6aad3014a8bb9e7f39d.jpeg)

1

追記

2019/07/12 07:42

投稿

退会済みユーザー
answer CHANGED
@@ -1,3 +1,5 @@
1
1
  30:00 でエラーが出たのは 30 時 00 分と解釈されたからだと思います。(TimeSpan 値は、[-]d.hh:mm:ss.ff で表され、hh は 24 時間制の時間となりますが、それに 30 と入力されたのでエラーになった)
2
2
 
3
- 00 分 00 秒以上、59 分 59 秒以下という範囲を超えたらエラーを出すにはデータアノテーション属性(RegularExpression または Range)を付与することで可能です。
3
+ 00 分 00 秒以上、59 分 59 秒以下という範囲を超えたらエラーを出すにはデータアノテーション属性(RegularExpression または Range)を付与することで可能です。
4
+
5
+ あと、未検証ですが、00:mm:ss という形でテキストボックスに入力する必要がありそうです。