asp.net-mvc
データアノテーション
サーチ…
前書き
データアノテーションをモデルクラスに追加することで、アプリケーションにバリデーションを追加できます。データアノテーションを使用すると、モデルプロパティに適用するルールを記述することができ、ASP.NET MVCはそれらを実行して適切なメッセージをユーザーに表示します。
ViewModelで使用される基本的な検証属性
モデル
using System.ComponentModel.DataAnnotations;
public class ViewModel
{
[Required(ErrorMessage="Name is required")]
public string Name { get; set; }
[StringLength(14, MinimumLength = 14, ErrorMessage = "Invalid Phone Number")]
[Required(ErrorMessage="Phone Number is required")]
public string PhoneNo { get; set; }
[Range(typeof(decimal), "0", "150")]
public decimal? Age { get; set; }
[RegularExpression(@"^\d{5}(-\d{4})?$", ErrorMessage = "Invalid Zip Code.")]
public string ZipCode {get;set;}
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string Email { get; set; }
[Editable(false)]
public string Address{ get; set; }
}
ビュー
// Include Jquery and Unobstructive Js here for client side validation
@using (Html.BeginForm("Index","Home") {
@Html.TextBoxFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
@Html.TextBoxFor(model => model.PhoneNo)
@Html.ValidationMessageFor(model => model.PhoneNo)
@Html.TextBoxFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
@Html.TextBoxFor(model => model.ZipCode)
@Html.ValidationMessageFor(model => model.ZipCode)
@Html.TextBoxFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
@Html.TextBoxFor(model => model.Address)
@Html.ValidationMessageFor(model => model.Address)
<input type="submit" value="submit" />
}
コントローラ
public ActionResult Index(ViewModel _Model)
{
// Checking whether the Form posted is valid one.
if(ModelState.IsValid)
{
// your model is valid here.
// perform any actions you need to, like database actions,
// and/or redirecting to other controllers and actions.
}
else
{
// redirect to same action
return View(_Model);
}
}
リモート検証
サーバー側にajaxリクエストを送信してチェックするために、入力コントロールに入力されたコンテンツが有効かどうかを確認するためのリモート検証。
ワーキング
RemoteAttribute
は、クライアントからのAJAX呼び出しを、検証されるフィールドの値を持つコントローラアクションにすることによって機能します。コントローラのアクションは、検証の成功または失敗を示すJsonResult
レスポンスを返します。あなたの行動からtrue
を返すことは、検証が合格したことを示します。それ以外の値は失敗を示します。 false
を返すと、属性に指定されたエラーメッセージが使用されます。文字列や整数などを返すと、エラーメッセージとして表示されます。エラーメッセージが動的である必要がある場合を除いて、trueまたはfalseを返し、バリデーターが属性で指定されたエラーメッセージを使用するようにしてください。
ViewModel
public class ViewModel
{
[Remote("IsEmailAvailable", "Group", HttpMethod = "POST", ErrorMessage = "Email already exists. Please enter a different email address.")]
public string Email{ get; set; }
}
コントローラ
[HttpPost]
public JsonResult IsEmailAvailable(string Email)
{
// Logic to check whether email is already registered or Not.
var emailExists = IsEmailRegistered();
return Json(!emailExists);
}
RemoteAttribute
AdditionalFields
プロパティを使用して、コントローラメソッドにモデルの追加のプロパティを渡すことができます。典型的なシナリオは、コントローラロジックが既存のレコードの値を無視できるように、モデルのIDプロパティを 'Edit'フォームに渡すことです。
モデル
public int? ID { get; set; }
[Display(Name = "Email address")]
[DataType(DataType.EmailAddress)]
[Required(ErrorMessage = "Please enter you email address")]
[Remote("IsEmailAvailable", HttpMethod="Post", AdditionalFields="ID", ErrorMessage = "Email already exists. Please enter a different email address.")]
public string Email { get; set; }
コントローラ
[HttpPost]
public ActionResult Validate(string email, int? id)
{
if (id.HasValue)
{
return Json(!db.Users.Any(x => x.Email == email && x.ID != id);
}
else
{
return Json(!db.Users.Any(x => x.Email == email);
}
}
その他の注意
デフォルトのエラーメッセージはわかりにくいので、 RemoteAttribute
を使用するときは常にデフォルトのエラーメッセージを上書きするようにしてRemoteAttribute
。
RequiredAttribute
Required
属性は、プロパティが必要であることを指定します。エラーメッセージは、属性のErrorMessage
プロパティを使用して指定できます。
最初に名前空間を追加します:
using System.ComponentModel.DataAnnotations;
プロパティに属性を適用します。
public class Product
{
[Required(ErrorMessage = "The product name is required.")]
public string Name { get; set; }
[Required(ErrorMessage = "The product description is required.")]
public string Description { get; set; }
}
また、グローバル化されたアプリケーションのエラーメッセージにリソースを使用することもできます。この場合、 ErrorMessageResourceName
リソースクラス(のリソースキーを指定する必要がありますresx
にsettedされなければならないファイル) ErrorMessageResourceType
:
public class Product
{
[Required(ErrorMessageResourceName = "ProductNameRequired",
ErrorMessageResourceType = typeof(ResourceClass))]
public string Name { get; set; }
[Required(ErrorMessageResourceName = "ProductDescriptionRequired",
ErrorMessageResourceType = typeof(ResourceClass))]
public string Description { get; set; }
}
StringLengthAttribute
StringLength
属性は、データフィールドで許容される文字の最小長と最大長を指定します。この属性は、プロパティ、パブリックフィールド、およびパラメータに適用できます。エラーメッセージは、属性のErrorMessage
プロパティで指定する必要があります。プロパティMinimumLength
とMaximumLength
はそれぞれ最小値と最大値を指定します。
最初に名前空間を追加します:
using System.ComponentModel.DataAnnotations;
プロパティに属性を適用します。
public class User
{
// set the maximum
[StringLength(20, ErrorMessage = "The username cannot exceed 20 characters. ")]
public string Username { get; set; }
[StringLength(MinimumLength = 3, MaximumLength = 16, ErrorMessage = "The password must have between 3 and 16 characters.")]
public string Password { get; set; }
}
また、グローバル化されたアプリケーションのエラーメッセージにリソースを使用することもできます。この場合、 ErrorMessageResourceName
リソースクラス(のリソースキーを指定する必要がありますresx
にsettedされなければならないファイル) ErrorMessageResourceType
:
public class User
{
[StringLength(20, ErrorMessageResourceName = "StringLength",
ErrorMessageResourceType = typeof(ResoucesKeys))]
public string Username { get; set; }
[StringLength(MinimumLength = 3,
MaximumLength = 16,
ErrorMessageResourceName = "StringLength",
ErrorMessageResourceType = typeof(ResoucesKeys))]
public string Password { get; set; }
}
範囲属性
Range
属性は、任意のプロパティまたはパブリックフィールドを飾ることができ、数値フィールドが有効であるとみなされる範囲を指定します。
[Range(minimumValue, maximumValue)]
public int Property { get; set; }
さらに、無効なデータが入力されたときにユーザーが受信したメッセージを設定するために使用できるオプションのErrorMessage
プロパティを受け取ります。
[Range(minimumValue, maximumValue, ErrorMessage = "{your-error-message}")]
public int Property { get; set; }
例
[Range(1,100, ErrorMessage = "Ranking must be between 1 and 100.")]
public int Ranking { get; set; }
正規表現の属性
[RegularExpression]
属性は、プロパティまたはパブリックフィールドを飾ることができ、プロパティと一致しなければならない正規表現を有効とみなすよう指定します。
[RegularExpression(validationExpression)]
public string Property { get; set; }
さらに、無効なデータが入力されたときにユーザーが受信したメッセージを設定するために使用できるオプションのErrorMessage
プロパティを受け取ります。
[RegularExpression(validationExpression, ErrorMessage = "{your-error-message}")]
public string Property { get; set; }
例
[RegularExpression(@"^[a-z]{8,16}?$", ErrorMessage = "A User Name must consist of 8-16 lowercase letters")]
public string UserName{ get; set; }
[RegularExpression(@"^\d{5}(-\d{4})?$", ErrorMessage = "Please enter a valid ZIP Code (e.g. 12345, 12345-1234)")]
public string ZipCode { get; set; }
属性の比較
Compare
属性は、モデルの2つのプロパティをCompare
ます。
エラーメッセージは、プロパティErrorMessage
またはリソースファイルを使用して指定できます。
Compare
属性include using
するには、次の名前空間にusing
します。
using System.ComponentModel.DataAnnotations;
次に、モデルの属性を使用できます。
public class RegisterModel
{
public string Email { get; set; }
[Compare("Email", ErrorMessage = "The Email and Confirm Email fields do not match.")]
public string ConfirmEmail { get; set; }
}
このモデルの検証時に、 Email
とConfirmEmail
値が異なると、検証は失敗します。
ローカライズされたエラーメッセージ
すべての検証属性と同様に、リソースファイルからのエラーメッセージを使用することもできます。このサンプルでは、エラーメッセージはリソースファイルResources
からロードされ、リソース名はCompareValidationMessage
です。
public class RegisterModel
{
public string Email { get; set; }
["Email", ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "CompareValidationMessage")]
public string ConfirmEmail { get; set; }
}
プロパティ名の文字列を避ける
プロパティ値として文字列を使用しないようにするには、C#6以降でnameof
keyword:
public class RegisterModel
{
public string Email { get; set; }
[Compare(nameof(Email), ErrorMessage = "The Email and Confirm Email fields do not match.")]
public string ConfirmEmail { get; set; }
}
エラーメッセージのプレースホルダ
エラーメッセージにプレースホルダを使用できます。プレースホルダ{0}
は現在のプロパティの表示名に置き換えられ、 {1}
は関連プロパティの表示名に置き換えられます。
public class RegisterModel
{
[Display(Name = "Email")]
public string Email { get; set; }
[Display(Name = "Confirm Email")]
[Compare("Email", ErrorMessage = "The '{1}' and '{0}' fields do not match.")]
public string ConfirmEmail { get; set; }
}
モデルの検証が失敗した場合、エラーメッセージは次のようになります。
「電子メール」と「電子メールの確認」フィールドが一致しません。
カスタム検証属性
フィールドが必要であるか、ある範囲の値であることを保証するなどの一般的なデータ検証ではないいくつかのルールを検証する際に、ビジネスロジックに固有のルールを検証する場合は、独自のカスタムバリデーターを作成できます。カスタム検証属性を作成するには、 ValidationAttribute
クラスをinherit
、そのIsValid
メソッドをoverride
inherit
必要がありoverride
。 IsValid
方法は、最初は、2つのパラメータを取るobject
と命名value
と第二はValidationContext object
と命名validationContext
。 Value
は、カスタムバリデーターが検証するフィールドの実際の値を参照します。
Custom Validator
を使用してEmail
を検証するとします。
public class MyCustomValidator : ValidationAttribute
{
private static string myEmail= "[email protected]";
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string Email = value.ToString();
if(myEmail.Equals(Email))
return new ValidationResult("Email Already Exist");
return ValidationResult.Success;
}
}
public class SampleViewModel
{
[MyCustomValidator]
[Required]
public string Email { get; set; }
public string Name { get; set; }
}
DotNetFiddleのデモはこちら
EDMxモデル - データ注釈
Edmxモデルインターネル
public partial class ItemRequest
{
public int RequestId { get; set; }
//...
}
これにデータアノテーションを追加する - このモデルを直接変更すると、モデルの更新が行われたときに変更が失われます。そう
この場合に属性を追加するには 'Required'
新しいクラスを作成する - 任意の名前
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
//make sure the namespace is equal to the other partial class ItemRequest
namespace MvcApplication1.Models
{
[MetadataType(typeof(ItemRequestMetaData))]
public partial class ItemRequest
{
}
public class ItemRequestMetaData
{
[Required]
public int RequestId {get;set;}
//...
}
}
または
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace YourApplication.Models
{
public interface IEntityMetadata
{
[Required]
Int32 Id { get; set; }
}
[MetadataType(typeof(IEntityMetadata))]
public partial class Entity : IEntityMetadata
{
/* Id property has already existed in the mapped class */
}
}
データベースの最初の実装のためのデータアノテーション(モデルコード自動生成)
[MetadataType(typeof(RoleMetaData))]
public partial class ROLE
{
}
public class RoleMetaData
{
[Display(Name = "Role")]
public string ROLE_DESCRIPTION { get; set; }
[Display(Name = "Username")]
public string ROLE_USERNAME { get; set; }
}
データベースを最初に使用し、モデルコードが自動生成された場合、このメッセージはモデルコードの上に表示されます。
このコードはテンプレートから生成されたものです。このファイルを手動で変更すると、アプリケーションで予期しない動作が発生する可能性があります。コードが再生成された場合、このファイルの手動による変更は上書きされます
データアノテーションを使いたいが、edmxをリフレッシュする場合に上書きしたくない場合は、上の例のような部分クラスをモデルフォルダに追加するだけです。