关于ASP.NET Core模型验证(何时使用可空和[Required])的问题:

huangapple go评论83阅读模式
英文:

Questions on ASP.NET Core model validation (when to use nullable and [Required])

问题

在我的ASP.NET Core 7 MVC应用程序中,我有以下模型:

public class Car
{
    public int Id { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set; }

    public DateTime WhenAdded { get; set; }

    public virtual Category Category { get; set; }

    public int CategoryId { get; set; }
}

当用户创建一辆车时,我想要确保在客户端和服务器上,每个属性都有值。对于jQuery非侵入式验证的库:

<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

我已经花了很多时间查找文档和Stack Overflow,关于哪些值会通过jQuery非侵入式验证和服务器端验证,但我仍然不确定。对于可空类型(在其中Visual Studio 坚持要求的类型)和 [Required] 属性,情况变得非常令人困惑。

关于我的Car模型,我猜如果Name字段为空,它既不会通过客户端验证,也不会通过服务器验证,但Price字段会通过,因为它的值为0?此外,创建表单将默认显示Price设置为0(这不是期望的行为)?如果是这样,我应该将PriceWhenAdded属性设为可空并添加[Required],然后只忽略提出的大量空值检查?

在创建一辆车的表单中,我想要一个带有默认<option value="">选择类别...</option><select>元素,当选择该选项时不应通过客户端/服务器端验证。非可空的CategoryCategoryId属性似乎适用于此?

您能告诉我是否有错误,并且我的Car模型应该实际上是什么样的吗?(我知道实际上应该使用CarViewModel,但这只是为了教育目的)

英文:

Say in my ASP.NET Core 7 MVC app I have the following model:

public class Car
{
	public int Id { get; set; }

	public string Name { get; set; }

	public decimal Price { get; set; }

	public DateTime WhenAdded { get; set; }

	public virtual Category Category { get; set; }

	public int CategoryId { get; set; }
}

When a user creates a car, I want to ensure on the client and on the server that every property has a value. Libraries for jQuery unobtrusive validation:

&lt;script src=&quot;~/lib/jquery/dist/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;~/lib/jquery-validation/dist/jquery.validate.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js&quot;&gt;&lt;/script&gt;

I've spent lots of time searching the docs and SO on what values pass the jQuery unobtrusive validation and server-side validation, but I still don't know for sure. It becomes very confusing with nullable types (on which Visual Studio insists) and [Required] attribute.

Regarding my Car model, I guess if the Name field is empty it won't pass neither client nor server validation, but Price field would because it evaluates to 0? Also the Create form will be displayed with Price set to 0 by default (which is not the desired behavior)? If so, I should make Price and WhenAdded properties nullable and [Required], and just ignore the numerous proposed null-checks.

In the Create form for a car I want to have a &lt;select&gt; element with the default &lt;option value=&quot;&quot;&gt;Choose category...&lt;/option&gt; which should not pass client/server-side validation when selected. Non-nullable Category and CategoryId properties seem to work for this?

Can you tell me if I'm wrong somewhere, and what should my Car model really look like? (I know I should actually use a CarViewModel, this is just for educational purposes)

答案1

得分: 2

你可以检查这部分内容:

> 验证系统将非可空参数或绑定属性视为具有[Required(AllowEmptyStrings = true)]属性。

.....

> 在服务器上,如果属性为null,则视为缺少必需值。非可空字段始终有效,并且不会显示[Required]属性的错误消息。
>
>
> 但是,非可空属性的模型绑定可能会失败,导致出现错误消息,例如"The value '' is invalid"。要为服务器端验证非可空类型指定自定义错误消息,您有以下选项:
>
> 使字段可为空(例如,使用decimal?代替decimal)。Nullable<T>值类型会像标准可空类型一样处理。
>
> 指定要由模型绑定使用的默认错误消息,如下例所示:

.AddMvcOptions(options =&gt;
    {
        options.MaxModelValidationErrors = 50;
        options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
            _ =&gt; &quot;The field is required.&quot;);
    });

我建议您尝试使用

[Required]
public int? CategoryId { get; set; }

以避免模型绑定错误。

如果您不希望用户选择默认选项,对于客户端验证,您需要一个像下面这样的selectlist项:

selist.Insert(0,new SelectListItem() { Text = &quot;Select&quot; ,Disabled=true,Selected=true});
英文:

You could check this part of document:

> The validation system treats non-nullable parameters or bound
> properties as if they had a [Required(AllowEmptyStrings = true)]
> attribute.

.....

> On the server, a required value is considered missing if the property
> is null. A non-nullable field is always valid, and the [Required]
> attribute's error message is never displayed.
>
>
> However, model binding for a non-nullable property may fail, resulting
> in an error message such as The value '' is invalid. To specify a
> custom error message for server-side validation of non-nullable types,
> you have the following options:
>
> Make the field nullable (for example, decimal? instead of decimal).
> Nullable<T> value types are treated like standard nullable types.
>
> Specify the default error message to be used by model binding, as
> shown in the following example:

.AddMvcOptions(options =&gt;
    {
        options.MaxModelValidationErrors = 50;
        options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
            _ =&gt; &quot;The field is required.&quot;);
    });

I Suggest you try with

[Required]
public int? CategoryId { get; set; }

to avoid model binding error

If you don't want user select the default option,for client validation,you need a selectlist item like below:

selist.Insert(0,new SelectListItem() { Text = &quot;Select&quot; ,Disabled=true,Selected=true});

关于ASP.NET Core模型验证(何时使用可空和[Required])的问题:

huangapple
  • 本文由 发表于 2023年6月5日 10:43:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76403238.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定