Visual Studio 2010 を使用して ASP.Net MVC4 のプロジェクトに取り組んでいます。カスタム データ注釈を実装する必要があります。私の要件は以下のようなものです
1) IP アドレスとホスト名の 2 つのフィールドがあります。ユーザーはそれらのいずれかを入力できます。しかし両方ではない
2) それに応じて検証する必要があり、ユーザーがそれらのいずれかに入力すると、他のものは自動的にクリアされる必要があります。
3) 両方を空にしてはならないことも検証する必要があります
上記の要件に基づいて、以下のような 2 つのカスタム属性を作成しました。
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public class IPAddressAttribute : ValidationAttribute, IClientValidatable
{
#region Propertie(s)
/// <summary>
/// Other dependent properties for validation
/// </summary>
public string CommaSeperatedProperties
{
get;
private set;
}
#endregion
#region Constructor(s)
/// <summary>
/// Parameterized constructor
/// </summary>
/// <param name="otherProperties">Other properties required for validation</param>
public IPAddressAttribute(string otherProperties): base(defaultErrorMessage)
{
if (!string.IsNullOrWhiteSpace(otherProperties))
{
this.CommaSeperatedProperties = otherProperties;
}
}
#endregion
#region Public Method(s)
public IEnumerable<ModelClientValidationRule>
GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
return new[] { new IPAddressValidationRule
(FormatErrorMessage(metadata.DisplayName),
CommaSeperatedProperties.Split(new char[]{','})) };
}
#endregion
#region Protected Method(s)
protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
{
// Validation logic goes here
}
#endregion
#region Field(s)
private const string defaultErrorMessage = "{0} is invalid";
#endregion
}
/// <summary>
/// Implements a custom validation attribute for Host name
/// </summary>
public class HostNameAttribute : ValidationAttribute, IClientValidatable
{
#region Propertie(s)
/// <summary>
/// Other dependent properties for validation
/// </summary>
public string CommaSeperatedProperties
{
get;
private set;
}
#endregion
#region Constructor(s)
/// <summary>
/// Parameterized constructor
/// </summary>
/// <param name="otherProperties">Other properties required for validation</param>
public HostNameAttribute(string otherProperties) : base(defaultErrorMessage)
{
if (!string.IsNullOrWhiteSpace(otherProperties))
{
this.CommaSeperatedProperties = otherProperties;
}
}
#endregion
#region Public Method(s)
public IEnumerable<ModelClientValidationRule>
GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
return new[] { new HostNameValidationRule
(FormatErrorMessage(metadata.DisplayName),
CommaSeperatedProperties.Split(new char[]{','})) };
}
#endregion
#region Protected Method(s)
protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
{
// Validation goes here
}
#endregion
#region Field(s)
private const string defaultErrorMessage = "{0} is invalid";
#endregion
}
私のjavascriptは以下のようなものです
// Register method for the client side validation of IP Address
$.validator.unobtrusive.adapters.add("ipaddress", ['id', 'hostname'],
function (options) {
var params = {
id: options.params.id,
hostname: options.params.hostname
};
options.rules['ipaddress'] = params;
options.messages['ipaddress'] = options.message;
});
// Register method for the client side validation of Host name
jQuery.validator.unobtrusive.adapters.add("hostname", ['id', 'ipaddress'],
function (options) {
var params = {
id: options.params.id,
ipaddress: options.params.ipaddress
};
options.rules['hostname'] = params;
options.messages['hostname'] = options.message;
});
// jquery validate function to validate an IP address
$.validator.addMethod("ipaddress", function (value, element, params) {
var result = true;
if (value != "") {
result = validateIPAddress(value);
// Clear the host name field, since they are mutually exclusive
var tempInd = element.id.search("IPAddress");
var hostNameCtrlID = element.id.substring(0, tempInd) + params.hostname;
if ($("#" + hostNameCtrlID).val() != "") {
$("#" + hostNameCtrlID).val("");
// trigger the validation in Host name field
//$("#remDevForm").valid();
if (result) {
result = $("#myForm").validate().element($("#" + hostNameCtrlID));
}
}
}
else {
// if both are empty, return false
var tempInd = element.id.search("IPAddress");
var hostNameCtrlID = element.id.substring(0, tempInd) + params.hostname;
if ($("#" + hostNameCtrlID).val() == "") {
result = false;
$.validator.messages.ipaddress = "Please enter either Hostname or IP Address";
}
}
return result;
}
);
// jquery validate function to validate Host name
$.validator.addMethod("hostname", function (value, element, params) {
var result = true;
if (value != "") {
var result = validateHostName(value);
// Clear the IP Address field, since they are mutually exclusive
var tempInd = element.id.search("HostName");
var ipAddressCtrlID = element.id.substring(0, tempInd) + params.ipaddress;
if ($("#" + ipAddressCtrlID).val() != "") {
$("#" + ipAddressCtrlID).val("");
// trigger the validation in IP Address field
//$("#myForm").valid();
if (result) {
result = $("#myForm").validate().element($("#" + ipAddressCtrlID));
}
}
}
else {
// if both are empty, return false
var tempInd = element.id.search("HostName");
var ipAddressCtrlID = element.id.substring(0, tempInd) + params.ipaddress;
if ($("#" + ipAddressCtrlID).val() == "") {
result = false;
$.validator.messages.hostname = "Please enter either Hostname or IP Address";
}
}
return result;
});
検証は個別にうまく機能します
クライアント側の検証で以下の問題に直面しています。
1) フィールドが空になると、検証はトリガーされません。これはバグですか?そのうちの 1 つだけが必須であるため、required を使用できないことに注意してください。何らかの値を入力すると、トリガーされます
2) 上記のように Java スクリプトでカスタム メッセージを取得できません。これの代わりに、常にデフォルトのエラー メッセージが表示されます。
長いコードであることは承知しており、申し訳ありません。誰が何が間違っているのかコメントできますか?