【问题标题】:ASP.NET 5: Nested model properties not validatingASP.NET 5:嵌套模型属性未验证
【发布时间】:2015-08-11 11:31:27
【问题描述】:

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

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 的!

【问题讨论】:

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


【解决方案1】:

我已经设法重现了您的问题,但就我而言,它工作得很好。

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

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

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

然后,我查看了 Register.cshtml 视图是如何获得灵感的。

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

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

最终结果是客户端验证在嵌套ViewModels 下工作得非常好,只要您视图中的字段遵守命名约定……当然,只要您有适当的validate.js 和@ 987654331@ 里面的文件。

不需要那个自定义的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,它呈现了一个部分,部分有以下内容:

<environment names="Development">
    <script src="~/lib/jquery-validation/jquery.validate.js"></script>
    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</environment>

【讨论】:

  • 服务器端验证呢?他没有提到客户端验证,他想使用 ModelState。
  • 感谢您的回答。我实际上也在使用 WebApi。没有客户端。
  • 你是对的。我没有看到你提到的最后一个注释是关于 WebAPI 的……我的错。
【解决方案2】:

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

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

{
    "name" : "name",
}

以上回复:

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

看起来是不是很正确?

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

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

回复:

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

如果您不想强制客户端发送没有任何值的对象,请创建扁平化视图模型。

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    相关资源
    最近更新 更多