1

Grettings мои друзья ...Защищенное MVC проверки 5 deppending

Так у меня есть набор флажков, которые я установил в моей модели:

[DisplayName("Páginas Consultadas")] 
    public List<CheckBoxes> PaginasConsultadas { get; set; } 

И у меня есть fieldtext ("ParaQueUsaEstasPag"), что требуется только, если любой из флажков ИТС проверено ...

[DisplayName("¿Para que usa esta(s) página(s)?")] 
    public string ParaQueUsaEstasPag { get; set; } 

и часть обзора:

<div class="col-lg-4" id="DivPagConsultadas"> 
     <span>@Html.LabelFor(model => model.PaginasConsultadas, @Html.DisplayNameFor(model => model.PaginasConsultadas))</span> 
     @{ 

    for (int i = 0; i < Model.PaginasConsultadas.Count(); i++) 
    { 
     <div class="checkbox"> 
      <label> 
       @Html.CheckBoxFor(model => model.PaginasConsultadas[i].ValorCheckBox) @Model.PaginasConsultadas[i].NombreCheckBox 
      </label> 
     </div> 
      @Html.HiddenFor(model => model.PaginasConsultadas[i].valorRespuesta, new { @Value = @Model.PaginasConsultadas[i].valorRespuesta }) 
    } 

     } 
    </div> 
</div> 
<br /> 
<div class="row"> 
    <div class="col-lg-12"> 

     @Html.LabelFor(model => model.ParaQueUsaEstasPag, @Html.DisplayNameFor(model => model.ParaQueUsaEstasPag)) 
     @Html.TextAreaFor(model => model.ParaQueUsaEstasPag, 5, 1, new { @class = "form-control", placeholder = "Esta pregunta se responde con base en la respuesta de la pregunta anterior" }) 
     @Html.ValidationMessageFor(model => model.ParaQueUsaEstasPag) 
    </div> 
</div> 
    <br /> 
<div class="row"> 
    <div class="col-lg-12"> 
     <button type="submit" class="btn btn-default" onclick="dispararPleaseWait()">Enviar Encuesta...</button> 
    </div> 
</div> 

Существует режим для этого, используя Foolproof (i.e [RequiredIf])?


Update: Следуйте идею ELAD, мой класс является следующим:

public class PagSeleccionadasValidation : ValidationAttribute, IClientValidatable 
{ 
    //todo 
    private readonly String _ChkPagSel; 

    public PagSeleccionadasValidation(String ChkPagSel) 
    { 
     _ChkPagSel = ChkPagSel; 
    } 

    public string P {get; set;} 
    protected override ValidationResult IsValid(object value, ValidationContext validationcontext) 
    { 
     if (value == null) 
     { 
      var PropertyInfo = validationcontext.ObjectType.GetProperty(_ChkPagSel); 
      var Lista = (List<CheckBoxes>)PropertyInfo.GetValue(validationcontext.ObjectInstance, null); 
      bool HayAlgunaCheck = Lista.Any(r => r.ValorCheckBox == true); 
      if (HayAlgunaCheck) 
      { 
       return new ValidationResult(this.ErrorMessageString); 
      } 
      else 
      { 
       return ValidationResult.Success; 
      } 
     } 
     return ValidationResult.Success;   
    } 
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 

     var rule = new ModelClientValidationRule 
     { 
      ErrorMessage = FormatErrorMessage(metadata.DisplayName), 
      ValidationType = "valpagselecc" 
     }; 
     rule.ValidationParameters["valpag"] = P; 

     yield return rule; 

    } 

} 

В JS называемых "JS-ValPagSel.js" я поставил это:

$.validator.unobtrusive.adapters.addSingleVal('valpagselecc', 'valpag'); 

$.validator.addMethod('valpagselecc', function (value, element, params) { 
//var checkValue = [Find element via jquery from the params.checkpropertinputname]; 
if (value) { 
    return false; // just for test 
} 
else { 
    return false; 
} 

});

И в представлении:

<script src="/Scripts/jquery-1.10.2.js"></script> 
<script src="/Scripts/jquery.validate.js"></script> 
<script src="/Scripts/jquery.validate.unobtrusive.min.js"></script> 
<script src="/Scripts/bootstrap.js"></script> 
<script src="/Scripts/respond.js"></script> 
<script src="/Scripts/blur.js"></script> 
<script src="/Scripts/jquery-ui-1.11.1.js"></script> 
<script src="/Scripts/jquery.validate.js"></script> 
<script src="/Scripts/jquery.validate.unobtrusive.js"></script> 
<script src="/Scripts/Custom/JS-ValPagSel.js"></script> 

<textarea class="form-control" cols="1" data-val="true" data-val-valpagselecc="El campo ¿Para que usa esta(s) página(s)? no es válido." data-val-valpagselecc-valpag="" id="ParaQueUsaEstasPag" name="ParaQueUsaEstasPag" placeholder="Esta pregunta se responde con base en la respuesta de la pregunta anterior" rows="5"></textarea> 
+0

Вы не можете установить этот тип проверки (условной) на 'уровне ViewModel'. Это должно быть в вашем «действии» –

+0

@ Dejan.S объясните сами. Я понял, что с Foolproof может быть возможным ... –

+0

Я имею в виду, я не думаю, что он обрабатывает список bools. Но посмотрите пример с Педро Матосом, создав обычную. –

ответ

0

Что бы я сделать, это поле [Required] и в вашем action проверки, если один из флажков проверяется. Если нет, вы можете удалить требуемую ошибку с ModelState перед проверкой ModelState.IsValid.

Пример:

if (Model.MyCheckBox.Checked) 
{ 
    ModelState.Remove("CheckboxName"); 
} 

if(ModelState.IsValid) 
{ 
    //Do stuff... 
} 

Поскольку вам требуется проверка на стороне клиента, а также, я добавлю еще один вариант. Вы можете использовать аннотацию пользовательских данных. Вам необходимо создать класс, который наследует от ValidationAttribute и реализует IClientValidatable.

public class RequiredIf : ValidationAttribute, IClientValidatable 
{ 
    private string _checkPropertyName; 

    public RequiredIf(string checkPropertyName) 
    { 
     _checkPropertyName = checkPropertyName; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     //Get PropertyInfo object 
     var phonePropertyInfo = validationContext.ObjectType.GetProperty(_checkPropertyName); 

     //Get value from property 
     bool checkValue = (bool)phonePropertyInfo.GetValue(validationContext.ObjectInstance, null); 

     if(!checkValue) 
      return new ValidationResult(this.ErrorMessageString); 

     return null; 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     ModelClientValidationRule rule = new ModelClientValidationRule(); 
     rule.ErrorMessage = this.ErrorMessageString; 
     rule.ValidationType = "requiredIf"; 

     rule.ValidationParameters.Add("checkpropertinputname", _checkPropertyName); 

     yield return rule; 
    } 
} 

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

На стороне клиента вам нужно JS вдоль этих линий:

$.validator.unobtrusive.adapters.add('requiredIf', ['checkpropertinputname'], 
    function (options) { 
     options.rules['requiredIf'] = options.params; 
     options.messages['requiredIf'] = options.message; 
    }); 

$.validator.addMethod('requiredIf', function (value, element, params) { 
    var checkValue = *[Find element via jquery from the params.checkpropertinputname]*; 

}); 
+0

Mmmm ... я тестирую это, но я не понимаю, потому что мне нужно сделать валидацию в представлении, аналогично сообщениям об ошибках Data Annotations .... вы следуете за мной? Спасибо за помощь моему другу –

+0

Я вижу, это решение поможет вам на стороне сервера, а не на клиенте. Я отредактирую ответ с другим решением. –

+0

Спасибо, я испытаю это –

2

В Foolproof у вас есть такие варианты [RequiredIf (...)]:

[RequiredIf] 
[RequiredIfNot] 
[RequiredIfTrue] 
[RequiredIfFalse] 
[RequiredIfEmpty] 
[RequiredIfNotEmpty] 
[RequiredIfRegExMatch] 
[RequiredIfNotRegExMatch] 

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

ИЛИ ...

Вы можете добавить свойство этого класса возвращать логическое значение и использовать RequiredIfTrue валидатор.

public class Checkboxes { 
    public bool IsAtLeastOneSelected 
    { 
     get{ 
      return PaginasConsultadas.Any(r => r.ValorCheckBox == [WHATEVER_VALUE MEANS_CHECKED]); 
     } 
    } 
} 

, а затем ...

[RequiredIfTrue("IsAtLeastOneSelected")] 
[DisplayName("¿Para que usa esta(s) página(s)?")] 
public string ParaQueUsaEstasPag { get; set; } 

Ваш ViewModel, вероятно, так:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.Mvc; 

public class TestViewModel 
{ 
    public List<Checkboxes> PaginasConsultadas { get; set; } 

    [RequiredIfTrue("IsAtLeastOneSelected")] 
    public string ParaQueUsaEstasPag { get; set; } 

    //You dont put that on your view. 
    //This is just used with RequiredIfTrue data anotation attribute so the Validator checks for it 
    public bool IsAtLeastOneSelected 
    { 
     get { return PaginasConsultadas.Any(r => r.ValorCheckBox); } 
    } 
} 

public class Checkboxes 
{ 
    //In order to check/uncheck you should use boolean for ValorCheckBox 
    public bool ValorCheckBox { set; get; } 
    public string NombreCheckBox { set; get; } 
} 

Остальное [конфигурация Защищенное] вы должны проверить документацию. Есть несколько скриптов, которые вы должны добавить, чтобы они работали.

http://foolproof.codeplex.com/ RequireIf Code = http://foolproof.codeplex.com/SourceControl/latest#Foolproof/RequiredIf.cs

+0

Можете ли вы помочь мне создать пользовательский атрибут? Потому что я делаю второй, но как я знаю, если пользователь проверяет или нет в представлении? –

+0

Можете ли вы изменить свой вопрос, чтобы добавить более подробную информацию о том, как вы делали просмотр? Это «IsAtLeastOneSelected» - это просто свойство readonly, которое поможет вам использовать атрибут RequiredIftrue. Пожалуйста, добавьте код просмотра, чтобы мы могли помочь вам лучше. –

+0

Готовый мой друг ... –

Смежные вопросы