首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否在MVC中将数据批注应用于视图模型的子属性?

是否在MVC中将数据批注应用于视图模型的子属性?
EN

Stack Overflow用户
提问于 2013-06-18 01:22:04
回答 4查看 3.9K关注 0票数 9

将简单的数据注释放在属性上是很棒的,

代码语言:javascript
复制
public class UnicornViewModel
{
   [Required]
   public string Name { get; set; }

但是假设我有这样的东西:

代码语言:javascript
复制
public class SuperPower
{
   public class Name { get; set; }
}

public class UnicornViewModel
{
   [Required]
   public string Name { get; set; }

   public SuperPower PrimarySuperPower { get; set; }

   public SuperPower SecondarySuperPower { get; set; }

如何在保留SecondarySuperPower.Name的可选属性的同时,对PrimarySuperPower.Name应用必需的属性?最好是1.一些绑定到客户端验证的东西,2.不需要任何特殊的处理,比如检查操作/自定义验证器中PrimarySuperPower.Name的值,如果值为空,则添加ModelState错误。如果有这样的东西就太好了:

代码语言:javascript
复制
   [Required(p => p.Name)]
   public SuperPower PrimarySuperPower { get; set; }

   public SuperPower SecondarySuperPower { get; set; }
EN

回答 4

Stack Overflow用户

发布于 2013-06-18 01:50:51

通常这是不支持的:ASP.NET MVC3 Validation of nested view model object fields

但是,您可以实现自定义模型验证,但是对客户端和服务器端执行此操作会变得相当复杂。

如果您有自己的SuperPower对象模板,它可以查找您自己创建的属性:

代码语言:javascript
复制
   [RequiredSubProperty("Name")]
   public SuperPower PrimarySuperPower { get; set; }

在模板中,只需将不显眼的验证属性传递到TextBoxFor的htmlAttributes参数或您使用的任何输入辅助对象中。

如果您没有使用模板,那么我将放弃所有这些,只在显示名字时将不显眼的验证属性传递到htmlAttributes参数中,而不是第二个。

另一种选择是将UnicornViewModel展平,如下所示

代码语言:javascript
复制
public class UnicornViewModel
{
   [Required]
   public string Name { get; set; }

   [Required]
   public string PrimarySuperPowerName { get; set; }

   public string SecondarySuperPowerName { get; set; }

这完全取决于您可以从更复杂的方法中获得多少重用。当我尝试大量使用模板时,我发现在不同的上下文中,关于模板的某些东西是没有意义的,因此我需要对象模板的许多变体(当子模板显示在父模板的页面上时,对子模板来说,拥有链接到父模板的详细信息的URL是没有意义的,因为您已经在该页面上,但在其他使用该子模板的地方,它应该显示指向父模板的链接)。最终,我不再使用模板,偶尔会在有大量重用的情况下使用部分参数。UI是橡胶与道路相遇的地方,ViewModels的结构不会像实体/业务模型那样好。

票数 1
EN

Stack Overflow用户

发布于 2017-06-08 05:59:34

这可能是一个迟来的答案,但我在搜索相同的东西时发现了这个问题。这就是我如何解决我的特殊情况的:

在我有这个之前:

代码语言:javascript
复制
public class ProductVm
{
    //+ some other properties        

    public Category Category {get; set;}
    public Category ParentCategory {get; set;}
}

为此,我想要像这样的东西:

代码语言:javascript
复制
public class ProductVm
{
    //some other properties        

    [DisplayName("Product Category", e => e.Description)]
    public Category Category {get; set;}
    [DisplayName("Parent Category", e => e.Description)]
    public Category ParentCategory {get; set;}
}

我不能在模型本身中输入这一点,因为两者都是同一个对象类。

我这样解决了它(因为在这种情况下我只需要读取Description值,而不是写它):

代码语言:javascript
复制
public class ProductVm
{
    //some other properties        

    public Category Category {get; set;}
    public Category ParentCategory {get; set;}

    [DisplayName("Product Category")]
    public string Category => Category.Description;

    [DisplayName("Main Category")]
    public string ParentCategory => ParentCategory.Description;
}

您可以稍微重写它以保留剩余的私有支持字段,并删除Category对象的属性封装,但在我的例子中,我仍然需要它们是公共的以用于其他用途。

关于上述问题,我会做以下几点:

代码语言:javascript
复制
public class UnicornViewModel
{
    [Required]
    public string Name { get; set; }

    public SuperPower PrimarySuperPower { get; set; }

    public SuperPower SecondarySuperPower { get; set; }

    [Required]
    public string PrimarySuperPowerName 
    {
        get { return PrimarySuperPower.Name; }
        set { PrimarySuperPower.Name = value; }
    }

    public string SecondarySuperPowerName 
    {
        get { return SecondarySuperPower.Name; }
        set { SecondarySuperPower.Name = value; }
    }
}

然后将我的视图绑定到字符串属性,并排除SuperPower属性。

票数 1
EN

Stack Overflow用户

发布于 2013-06-18 02:30:14

您不能使用标准数据属性执行此操作。您提到的所需语法在自定义实现中也是不可能的,因为没有对您尝试使用lambda的对象的引用。

使用第三方验证库可能会更好,比如FluentValidation。它为您的验证需求提供了相当大的灵活性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17153252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档