我正在尝试使用版本v4.0.30319的WCF
来验证System.ComponentModel.DataAnnotations.dll
服务请求。我将VS2010
与Target 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; }
}
我在这里错过了一些东西吗?请建议。
答案 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
被序列化为没有价值 - 而不是“不在那里”。