数据注释属性未在WCF中触发

时间:2013-12-06 17:39:46

标签: wcf data-annotations

我正在尝试使用版本v4.0.30319的WCF来验证System.ComponentModel.DataAnnotations.dll服务请求。我将VS2010Target Framework v4.0一起使用。

以下是我的示例请求。如果我使用WcfTestclient调用服务操作,即使我为null传递了无效值(String.Empty / "" / Name),注释也不会触发。

Request1

[MessageContract]
public class  AddUserRequest
{
    [MessageBodyMember]
    [Required(ErrorMessage = "Id is required.")]
    public int Id { get; set; }

    [MessageBodyMember]
    [Required(ErrorMessage = "Name is required.")]
    [StringLength(100, MinimumLength = 10, ErrorMessage = "Name length should be between 10 and 100")]
    public string Name { get; set; }
}

请求2

[DataContract]
public class User
{
    [DataMember(IsRequired = true)]
    [Required(ErrorMessage = "Id is required.")]
    public int Id { get; set; }

    [DataMember(IsRequired = true)]
    [Required(ErrorMessage = "Name is required.")]
    [StringLength(100, MinimumLength = 10, ErrorMessage = "Name length should be between 10 and 100")]
    public string Name { get; set; }
}

我在这里错过了一些东西吗?请建议。

1 个答案:

答案 0 :(得分:3)

来自msdn

  

System.ComponentModel.DataAnnotations命名空间提供了属性   用于为ASP.NET MVC和ASP.NET定义元数据的类   数据控制。

WCF不会立即处理来自该命名空间的属性。 你必须编写自己的逻辑来实现这一点。

Here is an article描述了WCF参数的自定义验证。

幸运的是,其他人已经这样做了here is a CodePlex project,它结合了WCF和Data Annotation类。这可能就是你需要的。

修改

DataMember.IsRequired表示给定成员必须出现在模型中。不是说它必须有价值。 这是为你的api版本。 例如,您可能在您的服务版本1中有这样的模型:

[DataContract]
public class User
{
    [DataMember]
    public int Id { get; set; }
}

这将序列化为(以简化方式):

<User>
<Id>19</Id>
</User>

任何与您的服务集成的客户端都会像这样发送You xml。

但是之后您将版本2中的模型更改为:

[DataContract]
public class User
{
    [DataMember]
    public int Id { get; set; }

    [DataMember]
    public String Name { get; set; }
}

但是您的客户端对新版本一无所知,并向您发送旧的xml。该xml将正确反序列化为您的新模型,但Name等于null。

通知您的旧客户此更改您需要将IsRequired=true添加到您的Name媒体资源中。这样WCF将为旧的xml返回一个错误,并且只接受这个结构:

<User>
<Id>19</Id>
<Name>Some Name</Name>
</User>

请注意,这不会使此类内容无效:

<User>
<Id>0</Id>
<Name />
</User>

您的案例中发生了什么。 Id不可为空,因此默认值为0。 并且Name被序列化为没有价值 - 而不是“不在那里”。