gpt4 book ai didi

c# - 在View中动态添加 "data-val"和 "data-val-required"是不是错了?

转载 作者:行者123 更新时间:2023-12-02 04:44:48 24 4
gpt4 key购买 nike

我有一个可以用 [Required] 属性装饰的 ViewModel(见下文)。我已经到了需要让客户端控制需要或不需要哪些字段的地步。他们可以通过 XML 配置这个槽,所有这些信息在模型首次创建时都存储在模型中。现在我有一些字段没有用 [Required] 装饰,但在提交之前仍然需要验证(根据“用户设置”)(例如 Phone 字段)。

public class MyBusinessObjectViewModel
{
[Required]
public string Email { get; set; } //compulsory

public string Phone { get; set; } //not (yet) compulsory, but might become
}

如果用户不输入电话 号码,数据仍会发布。不想弄乱自定义验证器,我只是将“data-val”和“data-val-required”属性添加到 Html,如下所示:

Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("data-val", "true");
dict.Add("data-val-required", "This field is required.");
@Html.TextBoxFor(x => x, dict);

这会强制对所有根据需要动态设置的属性进行客户端验证。这是好习惯吗?我可以期待什么样的副作用?

最佳答案

您应该考虑用您自己的 metadata provider 扩展元模型框架在您的站点配置和模型元数据之间进行实际绑定(bind)。您实际上可以设置 required property在元数据创建过程中将属性模型元数据标记为 true。我不记得这是否会导致内置编辑器模板生成属性,但我认为会。最坏的情况是您实际上可以创建一个新的 RequiredAttribute 并将其附加到该属性,这有点笨拙,但在某些情况下效果很好。

您也可以使用 IMetadataAware 来做到这一点属性,尤其是当 Required 是您的用户可以自定义的唯一元数据方面时,但实现实际上取决于您要执行的操作。

在您的特定情况下使用自定义 ModelMetadataProvider 的一个主要优点是您可以使用依赖注入(inject)(通过 ModelMetadataProviders )将您的客户设置持久性机制纳入范围,而使用数据属性您只能编写一个隔离的创建元数据模型后立即运行的方法。

这是自定义模型元数据提供程序的示例实现,您只需将客户端设置更改为您想要使用的任何设置即可。

已更新但根本没有测试

public class ClientSettingsProvider
{
public ClientSettingsProvider(/* db info */) { /* init */ }

public bool IsPropertyRequired(string propertyIdentifier)
{
// check the property identifier here and return status
}

}

public ClientRequiredAttribute : Attribute
{
string _identifier;
public string Identifier { get { return _identifer; } }
public ClientRequiredAttribute(string identifier)
{ _identifier = identifier; }
}

public class RequiredModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
ClientSettings _clientSettings;

public RequiredModelMetadataProvider(ClientSettings clientSettings)
{
_clientSettings = clientSettings;
}

protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
// alternatively here is where you could 'inject' a RequiredAttribute into the attributes list

var clientRequiredAttribute = attributes.OfType<ClientRequiredAttribute>().SingleOrDefault();
if(clientRequiredAttribute != null && _clientSettings.IsPropertyRequired(clientRequiredAttribute.Identifier))
{
// By injecting the Required attribute here it will seem to
// the base provider we are extending as if the property was
// marked with [Required]. Your data validation attributes should
// be added, provide you are using the default editor templates in
// you view.
attributes = attributes.Union(new [] { new RequiredAttribute() });
}

var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);

// REMOVED, this is another way but I'm not 100% sure it will add your attributes
// Use whatever attributes you need here as parameters...
//if (_clientSettings.IsPropertyRequired(containerType, propertyName))
//{
// metadata.IsRequired = true;
//}

return metadata;
}
}

用法

public class MyModel
{
[ClientRequired("CompanyName")]
public string Company { get; set; }
}

public class MyOtherModel
{
[ClientRequired("CompanyName")]
public string Name { get; set; }

public string Address { get; set; }
}

这两种模型都会根据您的客户端设置提供商验证字符串“CompanyName”。

关于c# - 在View中动态添加 "data-val"和 "data-val-required"是不是错了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20003716/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com