在ASP MVC3中使用ViewModel中的[RequiredIf]

问题描述 投票:2回答:2

我在我的MVC应用程序中使用custom RequiredIf attribute created by Simon Ince

我有一个viewmodel,它传递给视图,如下所示:

public class HistoryViewModel
{
    public Contact ContactModel { get; set; }
    public Account AccountModel { get; set; }
    public Person PersonModel { get; set; }
 }

我有一堆带有所有道具的模型(即contact.cs,account.cs,person.cs)

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool IsAdult { get; set; }        
    [RequiredIf("IsAdult", "Yes", Errormessage="Please leave a comment")]
    public string Comments { get; set; }
 }

当通过viewmodel传递时,RequiredIf验证似乎不起作用。如果我将属性直接移动到viewmodel中,它可以正常运行qzxswpoi [必需]`属性通过视图模型从模型中工作。

那么我需要将所有属性移动到viewmodel中,它们需要RequiredIf吗?或者还有另一种方法吗?

jquery asp.net-mvc-3 validation conditional
2个回答
6
投票

你试过. All other吗?它支持客户端支持的RequiredIf(以及其他一些人)。它有时可能有点儿马车,但最新版本并不坏。

以与上面相同的方式工作(我在切换到FoolProof之前尝试过)

MVC FoolProof validation

2
投票

The Problem

如果你看看你的剃刀视图发出的html,你会看到这里有什么问题。

如果没有viewmodel,我们应该生成以下代码(清理一下):

   public bool Married { get; set; }

    [RequiredIfTrue("Married")]
    public string MaidenName { get; set; }

使用viewmodel,我们得到:

<input type="checkbox" name="IsAdult" id="IsAdult" />
<input type="text" name="Comments" id="Comments"
       data-val-requiredif-dependprop="IsAdult" 
       data-val-requiredif-value="Yes"
       data-val-requiredif="Please leave a comment" />

只要属性嵌套在另一个属性中,MVC就会构建一堆前缀来生成唯一的ID和名称。您可以在第一种情况下看到,<input type="checkbox" name="PersonModel.IsAdult" id="PersonModel_IsAdult" /> <input type="text" name="PersonModel.Comments" id="PersonModel_Comments" data-val-requiredif-dependprop="IsAdult" data-val-requiredif-value="Yes" data-val-requiredif="Please leave a comment" /> 足以识别该字段,但是一旦嵌套,id就会发生变化。在不显眼的验证(存储在属性中的规则)中,我们需要了解如何验证元素的所有内容需要在IsAdult中发送,包括如何定位其他属性。

The Solution

类的数据属性永远不应该知道或关心它被调用的上下文,因此它将继续盲目地指出它所依赖的相对属性:

data-attributes

因此,我们必须在服务器或客户端上建立上下文。

在服务器上 - 不!

作为public bool IsAdult { get; set; } [RequiredIf("IsAdult", "Yes", Errormessage="Please leave a comment")] public string Comments { get; set; } 的一部分,您将拥有一个发出客户端验证规则的方法,如下所示:

public class RequiredIfAttribute : ValidationAttribute, IClientValidatable

这里的诱惑是导航public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { ModelClientValidationRule requiredIfRule = new ModelClientValidationRule(); requiredIfRule.ErrorMessage = ErrorMessageString; requiredIfRule.ValidationType = "requiredif"; requiredIfRule.ValidationParameters.Add("dependprop", this._propertyName); requiredIfRule.ValidationParameters.Add("value", Json.Encode(this._value)); yield return requiredIfRule; } 返回viewContext.ViewData.TemplateInfo,但从我所知,这GetFullHtmlFieldId

客户 - 不知道但工作:

在客户端上,我们将使用看起来像information isn't available yet的方法连接适配器:

something like this

请注意,这仍然只是采用普通的旧属性名称,并假设它可以用作ID来定位对象。

通过做出一些合理的假设,我们可以构建完整的依赖属性id。始终应该是requiredif调用元素与我们识别的属性在同一范围内(这就是我们如何通过反射在服务器上找到它)。

所以我们将从发件人那里获取该上下文,删除该属性的名称,并在$.validator.unobtrusive.adapters.add('requiredif', ['dependprop', 'value'], function (options) { options.rules["requiredif"] = { id: '#' + options.params['dependprop'], value: JSON.parse(options.params.value) }; options.messages['requiredif'] = options.message; }); 中附加我们自己的内容:

$.validator.unobtrusive.adapters.add

这应该有助于找到合适的客户端属性 - 然后编写您需要满足的任何其他条件。

© www.soinside.com 2019 - 2024. All rights reserved.