ASP.NET MVC 3 - НЕПРАВИЛЬНАЯ ПЕРЕДИТАЦИЯ Клиентской стороны для шаблонов редактора

StackOverflow https://stackoverflow.com/questions/5378520

Вопрос

Я новичок в ASP.NET MVC 3, столкнувшись с некоторыми проблемами, пытаясь реализовать ненавязчивую проверку на стороне клиента для шаблона редактора, который я создал для показа даты на заказ.

UI
Мне нужно показать дату в Три Texbox UI формат как

enter image description here


Я поставил Editortemplate для отображения даты в трех частях как

@model DateTime?

<table class="datetime">
<tr>
    <td>@Html.TextBox("Day", (Model.HasValue ? Model.Value.ToString("dd") : string.Empty)) </td>
    <td class="separator">/</td>
    <td>@Html.TextBox("Month", (Model.HasValue ? Model.Value.ToString("MM") : string.Empty))</td>
    <td class="separator">/</td>
    <td>@Html.TextBox("Year", (Model.HasValue ? Model.Value.ToString("yyyy") : string.Empty))</td>
</tr>
<tr>
    <td class="label">dd</td>
    <td/>
    <td class="label">mm</td>
    <td/>
    <td class="label">yyyy</td>
</tr>
</table>

Модель
Я должен связать дату поля рождения, которая является собственностью в субобект моей модели этой собственности, в этой структуре

MyModel
    --> MySubModel
          --> DateOfBirth

public class MySubModel
{
    ...

    [DataType(DataType.Date)]
    [Display(Name = "Date of birth")]
    [DateTimeClientValidation()]
    public DateTime DateofBirth { get; set; }

    ...
}

Валидация клиентов

Я разместил пользовательский атрибут проверки, который реализует iClientValidatable как

public class DateTimeClientValidationAttribute : ValidationAttribute, IClientValidatable
{
    ...

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        List<ModelClientValidationRule> clientRules = new List<ModelClientValidationRule>();

        //Combined date should be valid
        ModelClientValidationRule validDateRule = new ModelClientValidationRule
        {
            ErrorMessage = "Please enter a valid date.",
            ValidationType = "validdate"
        };
        validDateRule.ValidationParameters.Add("dayelement", metadata.PropertyName + ".Day");
        validDateRule.ValidationParameters.Add("monthelement", metadata.PropertyName + ".Month");
        validDateRule.ValidationParameters.Add("yearelement", metadata.PropertyName + ".Year");
        clientRules.Add(validDateRule);

        return clientRules;
    }
    ...
}

Я пытаюсь издавать имена элементов в текстовые поля дня, месяц и год здесь к элементам проверки на стороне клиента, чтобы позже написать метод проверки и адаптер на стороне клиента, который будет потреблять эти элементы и выполнять проверку на стороне клиента.

Вид
Теперь, чтобы использовать этот шаблон редактора, я вставил Вид Следующие строки

@model MyModel
...
<tr>
    <td class="editor-label">
        @Html.LabelFor(m => m.MySubModel.DateofBirth)
    </td>
    <td class="editor-field">
        @Html.EditorFor(m => m.MySubModel.DateofBirth)
        @Html.ValidationMessageFor(m => m.MySubModel.DateofBirth)
    </td>
</tr>
...

Добавлены все соответствующие файлы проверки jQuery в представлении в качестве ссылок

Вопросы

  1. Это не издает ненавязчивые атрибуты валидации JavaScript в HTML, хотя я реализовал IClientValidatable. Анкет Для цели тестирования, когда я ставлю тот же атрибут (DateTimeclientValidation) На другом свойстве в модели, которая не использовала этот шаблон редактора, тогда он испускал эти атрибуты валидации, он не испускает его только для этого шаблона редактора. Куда я мог пойти не так?
  2. Что касается проверки сообщений для шаблона редактора, правильно ли я положил его на вид или должен поместить его непосредственно в шаблон редактора (@Html.validationmessagefor (m => m.mysubmodel.dateofbirth))
  3. В этом примере я прямо в дизайне, я вставил DateTimeclientValidationAttribute, который на самом деле является атрибутом, который я накладываю на модель, но этот компонент немного знает об пользовательском интерфейсе (поскольку он пытается издавать название элементов дня, месяца и года и года), это заставляет модель немного знать о взгляде, AM Я ломаю здесь какие -либо принципы дизайна?
  4. В DateTimeclientValidationAttribute, Я пытаюсь издавать клиенту, чтобы сценарий клиента мог выполнять проверку дня, месяц и года. Но с тех пор, как модель свойство Дата рождения находится в подборке, фактическое имя элемента в сценарии Mysubobject.dateofbirth, что делает имя текстового поля дня Mysubobject.dateofbirth.day, как я могу найти это полностью квалифицированное название модели в GetClientValidationRules Метод, чтобы я мог излучать имя клиенту?

Спасибо за то, что терпеливы, чтобы зачитать все это, и за ответы

Это было полезно?

Решение

После некоторых усилий я сделал контроль над работой, вставая, если это полезно для кого -либо там.

Первая точка состоит в том, чтобы определить управление как

@model DateTime?

<table class="datetime">
<tr>
    <td>@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("dd") : string.Empty)) </td>
    <td class="separator">/</td>
    <td>@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("MM") : string.Empty))</td>
    <td class="separator">/</td>
    <td>@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("yyyy") : string.Empty))</td>
</tr>
<tr>
    <td class="label">dd</td>
    <td/>
    <td class="label">mm</td>
    <td/>
    <td class="label">yyyy</td>
</tr>
</table>

Убедитесь, что вы даете пустые струны как имя ко всем трем текстовым полям это заставляет структуру MVC генерировать то же самое имя соответствует модели Дата рождения Для всех трех текстовых полей на стороне клиента. Кроме того, ненавязчивые параметры проверки JavaScript будут сгенерированы для первого текстового поля в списке, поскольку это первое событие управления редактированием с именем модели.

На стороне клиента в любом случае на любом из этих текстовых поток запускает все соответствующие события проверки, поскольку все эти 3 текстовых поле имеют одинаковое имя.

Помимо регулярных подтверждений, таких как требуемые, ... мы должны написать пользовательскую подпрограмму проверки клиента, которая объединит все эти три значения и проверяет, является ли комбинированное значение формируемой допустимой датой. Это может быть достигнуто, как в отвечать дано Джефф.

Другие советы

Хорошо, так что несколько вещей. Во -первых, если это вообще возможно, не разделите дату на три поля. Вы сохраните себе мир головной боли, просто настроив его как одно поле с некоторой проверкой и, возможно, дата jqueryui.

Далее, в вашем пользовательском коде атрибута внутри DateTimeClientValidationAttribute вы никогда не проверяете, чтобы увидеть, действительна ли дата, реализуя IsValid:

protected override ValidationResult IsValid(object value, 
    ValidationContext validationContext) 
{
   ...
   // Put date parts together and check is valid...
   if (DateTime.TryParse(year+"/"+month+"/"+day, out dateResult))
      return ValidationResult.Success;

   // Not valid
   return new ValidationResult(String.Format(ErrorMessageString, 
      validationContext.DisplayName));
}

Затем вам придется создать ненавязчивый адаптер проверки и метод валидатора jQuery, который объединяет параметры и пытается разобрать дату:

jQuery.validator.unobtrusive.adapters.add(
    'validdate', // notice this is coming from how you named your validation rule
    ['dayelement'],
    ['monthelement'],
    ['yearelement']
    function (options) {
        options.rules['datepartcheck'] = options.params;
        options.messages['datepartcheck'] = options.message;
    }
);
jQuery.validator.addMethod('datepartcheck', function (value, element, params) {
    var year = params[2];
    var month = params[1];
    var day = params[0];

    var birthDate = year + '/' + month-1 + '/' + day;
    var isValid = true;

    try {
        // datepicker is a part of jqueryUI.
        // include it and you can take advantage of .parseDate:
        $.datepicker.parseDate('yy/mm/dd', birthDate);
    }
    catch (error) {
        isValid = false;
    }
    return isValid;
}, '');
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top