WebAPI验证装饰 - [DataMember]和[Required]之间的区别?

Rob*_*ous 1 entity-framework asp.net-web-api

我有以下内容:

[DataContract]
public class Video
{
    [Key]
    [DataMember(IsRequired = false)]
    [Required]
    public int VideoId { get; set; }

    [DataMember(IsRequired = false)]
    [Required]
    public int UserId { get; set; }

    [Required]
    [DataMember(IsRequired=true)]
    public string Title { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

这里的目标是通过DataMember装饰告诉WebAPI,我需要的所有内容都是标题 - 有效请求不需要其他两个属性.

然后我试图告诉Entity Framework/SQL数据库中需要其他属性.我将在我的服务或webapi层中分配它们.

如果我使用以下内容仅发送标题,我会得到

{"$ id":"1","message":"请求无效.","modelState":{"$ id":"2","video.VideoId":["需要值". ],"video.UserId":["UserId属性是必需的."]}}

我在这里误解了什么?据我所知,WebAPI不应该关心没有提供videoId.

Sim*_*ger 5

不同之处RequiredAttribute在于它仅用于模型验证,因为它的IsRequired属性DataMemberAttribute是对序列化器的提示,即"在序列化或反序列化时,应始终存在此属性".

DataMemberAttributeModelStateDictionary.IsValid属性和一般MVC/Web Api模型验证没有影响.

在您的方案中,您需要RequiredAttribute(或System.ComponentModel.DataAnnotations命名空间中的任何验证属性)

编辑:

理想情况下,您应该使用适合您的Api端点的不同模型,而不是直接适用于Entity Framework的模型.因为实体框架代码优先使用与MVC/Web Api相同的属性进行验证,所以如果它们不能一对一翻译,则不能将它们混合使用.在我看来,您应该在控制器中为请求创建一个单独的类.例如:

public class VideoModel
{
    public int? VideoId { get; set; }

    public int? UserId { get; set; }

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

}

// And your method
public HttpResponseMessage YourAction(VideoModel model)
{
    // Manipulate your model and map them to your Entity Framework's model
}
Run Code Online (Sandbox Code Playgroud)

注意使用int?.如果它们不是必需的并且保留为int,则默认为0.要么保留VideoModel为int并将0视为特殊值(但是,您将如何区分真正发送的请求0),或者您使用int?.HasValue它来了解它是否随请求一起发送.