asp: CustomValidator / OnServerValidate - PullRequest
3 голосов
/ 23 марта 2010

У меня есть CheckBoxList, который я пытаюсь проверить, установлен ли хотя бы один из флажков.

Markup:

<asp:CustomValidator ID="RequiredFieldValidator8" ValidationGroup="EditArticle"
    runat="server" ErrorMessage="At least one Category is required."
    OnServerValidate="topic_ServerValidate" />
<asp:CheckBoxList id="checkboxlistCategories" runat="server"></asp:CheckBoxList>

Код-за:

protected void topic_ServerValidate(object source, ServerValidateEventArgs args)
{
    int i = 0;
    foreach (ListItem item in checkboxlistCategories.Items)
    {
        if (item.Selected == true)
            i = i + 1;
    }
    if (i == 0)
        args.IsValid = false;
    else
        args.IsValid = true;
}

Если я добавлю ControlToValidate = "checkboxlistCategories" в элемент управления CustomValidator, он взорвется! Исключение, которое я получаю:

System.Web.HttpException: элемент управления 'checkboxlistCategories', на который ссылается свойство ControlToValidate объекта RequiredFieldValidator8

Я что-то упустил?

Ответы [ 5 ]

1 голос
/ 25 октября 2010

Вот более чистая jQuery реализация, которая позволяет одну ClientValidationFunction для любого количества CheckBoxList элементов управления на странице:

function ValidateCheckBoxList(sender, args) {
 args.IsValid = false;

 $("#" + sender.id).parent().find("table[id$="+sender.ControlId+"]").find(":checkbox").each(function () {
     if ($(this).attr("checked")) {
  args.IsValid = true;
  return;
     }
 });
}

Вот разметка:

<asp:CheckBoxList runat="server"
    Id="cblOptions" 
    DataTextField="Text" 
    DataValueField="Id" />

<xx:CustomValidator Display="Dynamic" 
        runat="server" 
        ID="cblOptionsValidator"
        ControlId="cblOptions"
        ClientValidationFunction="ValidateCheckBoxList" 
        ErrorMessage="One selection required." />

И, наконец, пользовательский валидатор, который позволяет клиентской функции получать целевой элемент управления по идентификатору:

public class CustomValidator : System.Web.UI.WebControls.CustomValidator
{
 public string ControlId { get; set; }

 protected override void OnLoad(EventArgs e)
 {
     if (Enabled)
         Page.ClientScript.RegisterExpandoAttribute(ClientID, "ControlId", ControlId);

     base.OnLoad(e);
 }
}
0 голосов
/ 17 июня 2010

Как упоминал Мехди, 4 парня рассказали об этом в статье, на которую он ссылается в своем ответе.

Для краткости, вот список кодов -

public class CheckBoxListRequiredFieldValidator : BaseValidator
{
    private ListControl _listctrl;

    public CheckBoxListRequiredFieldValidator()
    {
        base.EnableClientScript = false;
    }

    protected override bool ControlPropertiesValid()
    {
        Control ctrl = FindControl(ControlToValidate);

        if (ctrl != null)
        {
            _listctrl = (ListControl)ctrl;
            return (_listctrl != null);
        }
        else
            return false;  
    }

    protected override bool EvaluateIsValid()
    {
        return _listctrl.SelectedIndex != -1;
    }
}

Вставьте этот барсук в свою библиотеку пользовательских элементов управления и все готово.

НТН.

0 голосов
/ 23 марта 2010

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

0 голосов
/ 23 марта 2010

Может быть, я что-то упустил. Но CheckBoxList элемент управления не имеет ValidationPropertyAttribute. Таким образом, вы не можете использовать его как свойство ControlToValidate. Попробуйте это:

CheckBoxList.cs

[ValidationProperty("SelectedIndex")]
public class CheckBoxList : System.Web.UI.WebControls.CheckBoxList
{
}

Web.Config

<tagMapping>
  <add tagType="System.Web.UI.WebControls.CheckBoxList, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mappedTagType="Namespace.CheckBoxList, Assembly"/>
</tagMapping>

Так или иначе, Скотт Митчелл написал отличную статью об этом здесь .

0 голосов
/ 23 марта 2010

Учитывая, что метод проверки на стороне сервера topic_ServerValidate специально привязан к полю checkboxlistCategories, вам не нужно устанавливать свойство ControlToValidate.

Причиной того, что он «взрывается» при добавлении свойства ControlToValidate, является тип элемента управления, на который вы ссылаетесь - a CheckBoxList. При назначении ControlToValidate любому виду валидатора этот валидатор автоматически выполнит «непустую» проверку ссылочного элемента управления перед выполнением действительной логики валидации. Если поле пустое, проверка не будет выполнена (то есть проверка прошла успешно). Это, конечно, если вы не установите ValidateWhenEmpty = true. По-видимому, валидаторы не знают, как проверить, является ли CheckBoxList пустым, и вместо этого выдают исключение.

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

...