如何防止WCF服务接收包含空对象的Foo/Bar列表?
如何在WCF中阻止传入包含空Foo/Bar对象的列表?
嘿,针对你遇到的这个需求——阻止调用方向WCF服务发送包含空Foo/Bar对象的列表,WCF本身并没有直接内置的注解能一步到位实现,但我们可以通过几种方式来强制执行这个规则,下面给你详细说说:
1. 最简单直接:在操作方法内手动验证
这是最容易上手的方式,直接在SetFooBar方法里检查列表中的每个元素是否为空,如果发现空对象就抛出FaultException,调用方会收到明确的错误提示:
public bool SetFooBar(FooBar fb) { // 检查Foos列表是否包含空元素 if (fb.Foos != null && fb.Foos.Any(item => item == null)) { throw new FaultException("Foos列表中不允许包含空对象"); } // 检查Bars列表是否包含空元素 if (fb.Bars != null && fb.Bars.Any(item => item == null)) { throw new FaultException("Bars列表中不允许包含空对象"); } // 这里写你的业务逻辑 return true; }
2. 自定义验证属性+DataAnnotations验证
如果你想把验证逻辑和业务代码解耦,可以自定义一个验证属性,结合WCF的DataAnnotations验证机制:
第一步:创建自定义验证属性
using System.ComponentModel.DataAnnotations; using System.Collections; public class NoNullElementsAttribute : ValidationAttribute { public override bool IsValid(object value) { var enumerable = value as IEnumerable; if (enumerable == null) { // 如果列表本身为null,可以交给[Required]属性来验证(如果需要的话) return true; } foreach (var item in enumerable) { if (item == null) { return false; } } return true; } }
第二步:在DataContract属性上标记验证
[DataContract] public class FooBar { [DataMember] public string ExternalId; [DataMember] public string Something; [DataMember] [NoNullElements] // 如果还要求列表本身不能为null,可以再加[Required] // [Required] public List<Foo> Foos; [DataMember] [NoNullElements] public List<Bar> Bars; }
第三步:启用WCF的验证行为
你需要在服务端配置或者代码中开启DataAnnotations验证:
var serviceHost = new ServiceHost(typeof(FooBarService)); foreach (var endpoint in serviceHost.Description.Endpoints) { foreach (var operation in endpoint.Contract.Operations) { var dataContractBehavior = operation.Behaviors.Find<DataContractSerializerOperationBehavior>(); if (dataContractBehavior != null) { dataContractBehavior.ValidationEnabled = true; } } } serviceHost.Open();
这样当调用方传入包含空元素的列表时,WCF会自动触发验证并返回错误。
3. 利用DataContract的序列化回调方法
还可以在FooBar类中使用WCF的序列化回调方法,在反序列化完成后进行验证:
[DataContract] public class FooBar { [DataMember] public string ExternalId; [DataMember] public string Something; [DataMember] public List<Foo> Foos; [DataMember] public List<Bar> Bars; [OnDeserialized] private void OnDeserialized(StreamingContext context) { if (Foos != null && Foos.Any(item => item == null)) { throw new SerializationException("Foos列表中不能包含空对象"); } if (Bars != null && Bars.Any(item => item == null)) { throw new SerializationException("Bars列表中不能包含空对象"); } } }
这种方式会在对象反序列化完成后立即执行检查,一旦发现空元素就抛出序列化异常,阻止后续处理。
总结一下,虽然WCF没有直接的内置注解来实现这个需求,但通过上面几种方法都能强制执行“列表中不能包含空Foo/Bar对象”的规则,你可以根据自己的代码结构选择最适合的方式~
内容的提问来源于stack exchange,提问作者xdtTransform
相关产品推荐
相关产品推荐

