有条件地使 MVC 类属性/类成为必需

发布于 2024-12-02 09:37:16 字数 253 浏览 2 评论 0原文

我有一个 Address 类,用于模型中的 MailingAddress 和 BillingAddress 属性。我希望需要 MailingAddress,而不是 BillingAddress,但我没有找到使用 DataAnnotations 执行此操作的方法。

如果我能够在 MailingAddress 属性上设置 [Required] 属性,并以某种方式定义 Address 类应该如何处理所需逻辑的逻辑,我觉得这将是一个简单的解决方案。

有什么想法吗?

I have an Address class that is used for both a MailingAddress and BillingAddress property in my Model. I want the MailingAddress to be required, but not the BillingAddress, but am not seeing a way to do this with DataAnnotations.

If I were able to set the [Required] attribute on the MailingAddress property and somehow define the logic for how the Address class is supposed to handle the required logic, I feel like that would be a simple solution.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

掩于岁月 2024-12-09 09:37:16

如果您的问题是如何在您自己的逻辑中使用必需属性,那么答案是使用反射。如果这不是你的问题,请原谅我。

获取相关类型的所有属性,然后查看它是否用RequiredAttribute 修饰。

class ParentClass
{
      [Required]
      public Address MailingAddress { get; set; }

      public Address BillingAddress { get; set; }
}

(...)

Type t = typeof(ParentClass);

foreach (PropertyInfo p in t.GetProperties())
{
    Attribute a = Attribute.GetCustomAttribute(p, typeof(RequiredAttribute));
    if (a != null)
    {
          // The property is required, apply your logic
    }
    else
    {
          // The property is not required, apply your logic
    }
}

编辑:修复了代码中的拼写错误

编辑2:扩展代码示例

If your question is how to use the Required attribute in your own logic, the answer is by use of reflection. Forgive me if that is not your question.

Get all properties from the type in question, then see if it is decorated with a RequiredAttribute or not.

class ParentClass
{
      [Required]
      public Address MailingAddress { get; set; }

      public Address BillingAddress { get; set; }
}

(...)

Type t = typeof(ParentClass);

foreach (PropertyInfo p in t.GetProperties())
{
    Attribute a = Attribute.GetCustomAttribute(p, typeof(RequiredAttribute));
    if (a != null)
    {
          // The property is required, apply your logic
    }
    else
    {
          // The property is not required, apply your logic
    }
}

Edit: Fixed a typo in code

Edit 2: Extended code example

七堇年 2024-12-09 09:37:16

这只是我脑海中突然出现的一个奇怪的现象:

一个简单的解决方案可能是将 Address 子类化为OptionalAddress。

我不认为必需的属性会继承到子类。

如果需要的话,[AttributeUsage (Inherited = False)]也会浮现在脑海中。

更接近 MVC 的解决方案可能是实现自定义模型绑定器(完全未经测试):

public override object BindModel(ControllerContext controllerContext,
    ModelBindingContext bindingContext)
        {
            var address = base.BindModel(controllerContext, bindingContext) as Address;
            if (bindingContext.ModelName.EndsWith("BillingAddress"))
            {
                foreach (PropertyInfo p in address.GetType().GetProperties())
                {
                Attribute a = Attribute.GetCustomAttribute(p, typeof(RequiredAttribute));
                if (a != null 
                    && propertyInfo.GetValue(address, null) == null 
                    && bindingContext.ModelState[bindingContext.ModelName 
                       + "." + p.Name].Errors.Count == 1)
                {
                    bindingContext.ModelState[bindingContext.ModelName + "." + p.Name].Errors.Clear();
                }
            }
            return address;
        }

This is just an odd quirk which popped into my head:

A simple solution might be to subclass Address to OptionalAddress.

I don't think the Required attributes would be inherited to the child class.

[AttributeUsage (Inherited = False)] also comes to mind if needed.

A more MVCish solution might be to implement a custom model binder (completely untested):

public override object BindModel(ControllerContext controllerContext,
    ModelBindingContext bindingContext)
        {
            var address = base.BindModel(controllerContext, bindingContext) as Address;
            if (bindingContext.ModelName.EndsWith("BillingAddress"))
            {
                foreach (PropertyInfo p in address.GetType().GetProperties())
                {
                Attribute a = Attribute.GetCustomAttribute(p, typeof(RequiredAttribute));
                if (a != null 
                    && propertyInfo.GetValue(address, null) == null 
                    && bindingContext.ModelState[bindingContext.ModelName 
                       + "." + p.Name].Errors.Count == 1)
                {
                    bindingContext.ModelState[bindingContext.ModelName + "." + p.Name].Errors.Clear();
                }
            }
            return address;
        }
糖果控 2024-12-09 09:37:16

之前提出的问题有很多选项:

ASP.NET MVC 条件验证

您需要吗这个验证是否在客户端完成?

IValidateableObject 将与任何现有属性结合使用,并可以提供额外的自定义验证。

Many options available at this previously asked question:

ASP.NET MVC Conditional validation

Do you need this validation done on the client side or not?

IValidateableObject will be used in conjunction with any of your existing attributes and can provide for the additional custom validation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文