Пользовательский атрибут ValidationAttribute не запускает вызов функции IsValid в модели представления - PullRequest
6 голосов
/ 06 октября 2011

Я создал свой собственный ValidationAttribute:

public class UrlValidationAttribute : ValidationAttribute
{
    public UrlValidationAttribute() {}

    public override bool IsValid(object value)
    {
        if (value == null)
            return true;

        var text = value as string;
        Uri uri;

        return (!string.IsNullOrWhiteSpace(text) && 
                Uri.TryCreate(text, UriKind.Absolute, out uri));
    }
}

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

public class DeviceAttribute
{
    public DeviceAttribute(int id, attributeDefinition, String url)
    {
        ID = id;
        Url = url;
    }

    public int ID { get; set; }

    [UrlValidation]
    public String Url { get; set; }
}

Модель представления используется в частичном представлении следующим образом:

@model List<ICMDB.Models.DeviceAttribute>

<table class="editor-table">

@foreach (var attribute in Model)
{
    <tr>

        @Html.HiddenFor(a => attribute.ID)

        <td class="editor-label">
            @Html.LabelFor(a => attribute.Url)
        </td>

        <td class="editor-field">
            @Html.TextBoxFor(a => attribute.Url)            
            @Html.ValidationMessageFor(a => attribute.Url)
        </td>

    </tr>
}

</table>

По неизвестной причине, в то время как конструктор для UrlValidationAttribute запускает IsValidфункция не срабатываетЕсть идеи?

Редактировать: При дальнейшем исследовании кажется, что это происходит потому, что модель вида DeviceAttribute на самом деле является моделью вида для частичного.На всю страницу передается другая модель представления, которая содержит список DeviceAttribute моделей представления.Поэтому, когда вызывается действие моего контроллера, создается модель полного просмотра страницы и заполняются ее значения, но модели представления DeviceAttribute не создаются, поэтому проверка не выполняется.

1 Ответ

0 голосов
/ 06 октября 2011

Я бы рекомендовал вам использовать шаблоны редактора вместо написания циклов foreach.Я полагаю, что ваша модель основного вида выглядит примерно так:

public class MyViewModel
{
    public List<DeviceAttribute> Devices { get; set; }
    ...
}

Теперь в вашем основном представлении:

@model MyViewModel
@using (Html.BeginForm())
{
    <table class="editor-table">
        @Html.EditorFor(x => x.Devices)
    </table>
    <input type="submit" value="OK" />
}

и в соответствующем шаблоне редактора (~/Views/Shared/EditorTemplates/DeviceAttribute.cshtml):

@model DeviceAttribute
<tr>
    @Html.HiddenFor(x => x.ID)

    <td class="editor-label">
        @Html.LabelFor(x => x.Url)
    </td>

    <td class="editor-field">
        @Html.TextBoxFor(x => x.Url)            
        @Html.ValidationMessageFor(x => x.Url)
    </td>
</tr>

А ваше действие POST возвращает модель представления обратно:

[HttpPost]
public ActionResult Index(MyViewModel model)
{
    ...
}

Теперь механизм связывания модели по умолчанию успешно свяжет все значения в модели представления и подтвердит правильность запуска.

Вот хороший пост в блоге о шаблонах.

...