ASP.NET 5:未验证的嵌套模型属性

时间:2015-08-11 11:31:28

标签: c# asp.net asp.net-core asp.net-core-mvc dnx

我添加了以下过滤器,以便在模型验证错误时返回错误请求:

public class ValidateModelFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }

        base.OnActionExecuting(context);
    }
}

我有一个双层模型,即:

public class PersonModel
{
    [Required] // This works!
    public string Name { get; set; }

    [Required] // This works!
    public AddressModel Address { get; set; }
}

public class AddressModel
{
    [Required] // This DOESN'T work :(
    public string Street { get; set; }

    [Required] // This DOESN'T work :(
    public string City { get; set; }
}

此处的问题是只验证PersonModel的属性。

为什么AddressModel属性无法验证?

注意:这适用于WebApi!

2 个答案:

答案 0 :(得分:0)

我设法重新创建了你的问题但在我的情况下,它运作得很好。

唯一的区别是我没有像你那样创建自定义FilterAttribute

简而言之,我使用VS 2015创建了一个新的MVC 6应用程序。我在ASP.NET 5预览模板中选择了 Web应用程序并保留了个人用户帐户作为身份验证。

通过这样做,这使我能够拥有一个正常运行的样本,而无需添加所有jquery文件等等。

然后我看了Register.cshtml视图是如何为灵感而做的。

我成功创建了两个模型PersonModelAddressModel,并添加了与您相同的属性。

然后我创建了一个新的Controller和两个IActionResult。一个用于呈现视图(强类型),另一个用于发布<form>

最终结果是,只要您的视图中的字段尊重命名约定,客户端验证就可以与嵌套的ViewModels完美匹配,当然,只要您拥有适当的{{1那里有}和validate.js个文件。

无需自定义validate.unobtrusive.js

这是我的观点:

FilterAttribute

请注意尊重嵌套<form asp-controller="NewController" asp-action="Index" method="post" class="form-horizontal" role="form"> <h4>Create a new account.</h4> <hr /> <div asp-validation-summary="ValidationSummary.All" class="text-danger"></div> <div class="form-group"> <label asp-for="Name" class="col-md-2 control-label"></label> <div class="col-md-10"> <input asp-for="Name" class="form-control" /> <span asp-validation-for="Name" class="text-danger"></span> </div> </div> <div class="form-group"> <label asp-for="Address.Street" class="col-md-2 control-label"></label> <div class="col-md-10"> <input asp-for="Address.Street" class="form-control" /> <span asp-validation-for="Address.Street" class="text-danger"></span> </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <button type="submit" class="btn btn-default">Register</button> </div> </div> </form> @section Scripts { @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } } 的字段的Address.Street命名约定。

另请注意呈现部分的ViewModels,部分具有以下内容:

@section Scripts

答案 1 :(得分:0)

它不起作用,因为如果父模型为null,则实现不检查嵌套属性。这是有道理的,因为没有什么可以验证的!

下面将导致验证错误,指出地址属性缺失

{
    "name" : "name",
}

上述回应:

{
  "Address": [
    "Field Address is required."
  ]
}

似乎不正确吗?

要验证地址,您需要将其作为空对象或完整对象提供,并将相应的属性设置为空或空:

{
     "name" : "name",
     "address" : {
     }
}

响应:

{
  "Address.Street": [
    "Field Street is required."
  ],
  "Address.City": [
    "Field City is required."
  ]
}

如果您不希望强制客户端发送对象(如果没有任何值),请创建展平视图模型。

希望这有帮助