Мне не удалось запустить мой метод проверки на стороне клиента после настройки проверки в соответствии с различными источниками. После долгих усилий я обнаружил, что изменение порядка загрузки скриптов решило проблему. Я предоставил ответ, чтобы показать полную настройку пользовательского атрибута RequiredIf для asp.net core 3.0 MVC. Надеюсь, это сэкономит другим людям драгоценное время.
Как настроить проверку на стороне клиента для пользовательского атрибута RequiredIf для Asp.NET Core 3.0
Ответы (1)
Создайте новый класс, наследующий ValidationAttribute и IClientModelValidator:
public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
{
private string PropertyName { get; set; }
private object DesiredValue { get; set; }
public RequiredIfAttribute(string propertyName, object desiredvalue)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
object instance = context.ObjectInstance;
Type type = instance.GetType();
object propertyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
if ((value == null && propertyvalue == DesiredValue) || (value == null && propertyvalue != null && propertyvalue.Equals(DesiredValue)))
{
return new ValidationResult(ErrorMessage);
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-requiredif", errorMessage);
MergeAttribute(context.Attributes, "data-val-requiredif-otherproperty", PropertyName);
MergeAttribute(context.Attributes, "data-val-requiredif-otherpropertyvalue", DesiredValue == null? "": DesiredValue.ToString());
}
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
}
}
Примените атрибут в своей модели в качестве аннотации над своим свойством:
[Display(Name = "Effective Date Column Name")]
[RequiredIf("EffectiveDate", null, ErrorMessage = "Effective Date Column Name is required or Enter an Effective Date.")]
public string ColumnNameEffectiveDate { get; set; }
[Display(Name = "Enter Effective Date")]
public DateTime? EffectiveDate { get; set; }
Добавьте элементы проверки в свой html:
<fieldset>
<legend class="w-auto">Step 4: Set Effective Date</legend>
<div class="form-row">
<div class="form-group col-12">
<small class="form-text">Select the name of the date column to import, or enter a date.</small>
</div>
<div class="form-group col-12 col-lg-4 columnheader">
<label asp-for="@Model.ColumnNameEffectiveDate" class="slightlyBold"></label>
<select class="form-control selectpicker"
asp-for="@Model.ColumnNameEffectiveDate">
<option value="">Nothing selected</option>
</select>
<span asp-validation-for="@Model.ColumnNameEffectiveDate" class="text-danger"></span> <==== HERE
</div>
<div class="form-group col-12 col-lg-2 text-center">
<label class="slightlyBold pt-4">OR</label>
</div>
<div class="form-group col-12 col-lg-4">
<label asp-for="@Model.EffectiveDate" class="slightlyBold">Enter Effective Date:</label>
<input type="text" class="datepicker form-control" asp-for="@Model.EffectiveDate">
</div>
</div>
</fieldset>
Во время выполнения HTML изменится, чтобы включить теги проверки:
<select class="form-control selectpicker" data-val="true" data-val-requiredif="Effective Date Column Name is required or Enter an Effective Date." data-val-requiredif-otherproperty="EffectiveDate" data-val-requiredif-otherpropertyvalue="" id="ColumnNameEffectiveDate" name="ColumnNameEffectiveDate" disabled="disabled">
<option value="">Nothing selected</option>
</select>
Создайте файл javascript, который добавит новое правило в ненавязчивый адаптер (я назвал свой файл customValidationRules.js):
$(function () {
jQuery.validator.unobtrusive.adapters.add("requiredif", ["otherproperty", "otherpropertyvalue"],
function (options) {
options.rules["requiredif"] = options.params;
options.messages["requiredif"] = options.message
});
}(jQuery));
и второй файл для запуска метода для этого правила (я назвал свой файл customValidationMethods.js):
(function ($) {
jQuery.validator.addMethod("requiredif",
function (value, element, parameters) {
var targetId = parameters.otherproperty;
var targetValue = parameters.otherpropertyvalue;
var otherpropertyvalue = (targetValue == null || targetValue == undefined ? "" : targetValue).toString();
var otherpropertyElement = $('#' + targetId);
if (!value.trim() && otherpropertyElement.val() == otherpropertyvalue) {
var isValid = $.validator.methods.required.call(this, value, element, parameters);
return isValid;
}
return true;
}
);
})(jQuery);
Обязательно укажите ссылки на необходимые сценарии проверки для страницы. Порядок сценариев - это то, что заставило мою проверку на стороне клиента начать работу для пользовательского атрибута:
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-ajax-unobtrusive/dist/jquery.unobtrusive-ajax.js"></script>
@*These 4 validation scripts must not be changed*@
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script> <==== HERE
<script src="~/js/customValidationMethods.js"></script> <==== HERE
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script> <==== HERE
<script src="~/js/customValidationRules.js"></script> <==== HERE
@*These 4 validation scripts must not be changed*@
<script src="~/lib/popper.js/umd/popper.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
person
Kellie
schedule
01.09.2020