【问题标题】:ASP.NET MVC - How to implement an optional nested model with required fields?ASP.NET MVC - 如何使用必填字段实现可选嵌套模型?
【发布时间】:2014-01-26 07:36:32
【问题描述】:

我目前正在一个 ASP.NET MVC4 应用程序中实现一个表单,但我似乎找不到关于输入验证的良好且可维护的解决方案。给定以下(简化的)模型:

public class PersonalData
{
    [Required]
    public string FirstName { get; set; }

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

    [Required]
    public AddressData ResidentialAddress { get { return residentialAddress; } }
    private readonly AddressData residentialAddress = new AddressData();

    public AddressData PostalAddress { get; set; }
}

public class AddressData
{
    [Required]
    public string ZipCode { get; set; }

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

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

    [Required]
    public int HouseNumber { get; set; }
}

我认为这个模型定义几乎不言自明:我能够将“PersonalData”类上的属性声明为“必需”,并且我也能够在“AddressData”上做同样的事情-模型。这种方法适用于“ResidentialAddress”属性,但是对于可选的嵌套模型(例如“PostalAddress”属性中提供的模型)会变得很棘手。

简单地说:

  • PersonalData”模型上的所有字符串属性都是必需的;
  • 需要存储在“ResidentialAddress”属性中的“AddressData”对象上的所有字符串属性;
  • PostalAddress”是可选的:存储在“PostalAddress”属性中的“AddressData”对象上的所有字符串属性都是必需的如果为其指定了“AddressData”实例。

“扁平化”PersonalData 模型对我来说似乎不是一个理想的解决方案,尤其是考虑到我们正在使用 EditorTemplate 的事实。

我有哪些选择?我在根本上做错了什么吗?是否有普遍支持的技术?

【问题讨论】:

  • 恐怕没有简单(直接)的解决方案。至少没有我能想到的(或找到,对于那个母校)。请查看this (identical) question。在相关的说明中,我更喜欢编写“完整”模型,即使这意味着结合多个业务模型。
  • 这(是否有单独的邮政地址)进入业务逻辑。您将无法以声明方式解决它。恐怕你需要编写一些额外的代码行来处理这个问题......
  • 托马斯和安德烈;感谢您的快速回复。我实际上设法找到了一个适合我需要的解决方案,但您的意见肯定要考虑在内。谢谢!

标签: c# asp.net-mvc-4


【解决方案1】:

我实际上找到了适合我需要的解决方案!假设一个控制器有这个方法:

[HttpPost]
public ActionResult Edit(PersonalData model)
{
    if (ModelState.IsValid)
    {
        // Success
        return Redirect("NextAction");
    }
    return View(model);
}

此处“模型”参数中使用的“PersonalData”对象的实例化是基于正在发送的 POST 变量的反序列化。

现在,如果正在发送以下 POST 变量:

  • 名字:“约翰”
  • 姓氏:“Doe”
  • ResidentialAddress.ZipCode:'1234AB'
  • ResidentialAddress.City:“我的城市”
  • ResidentialAddress.Street:“我的街道”
  • ResidentialAddress.HouseNumber:'123'

然后它将被序列化为“PersonalData”实例,在该实例上,“ResidentialAddress”属性必须分配有有效的“AddressData”实例。 (MVC 似乎会自动处理这个问题)。

存在“PostalAddress”相关的 POST 变量,如下...

  • PostalAddress.ZipCode:'1234AB'
  • PostalAddress.City:“我的城市”
  • PostalAddress.Street:“我的街道”
  • PostalAddress.HouseNumber:'123'

...似乎控制序列化是否会导致将“AddressData”实例实例化为“PostalAddress”属性,这完全涵盖了我想要的情况。

底线:保持对发送的 POST 变量的控制,您应该没问题!我希望这可以帮助任何人;欢迎提出建议和/或 cmets!

【讨论】:

    猜你喜欢
    • 2020-02-27
    • 1970-01-01
    • 2015-06-04
    • 2023-01-18
    • 2021-06-28
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多