在WCF服务返回DataContract并且枚举成员具有无效值(Enum类型中不存在int)的情况下,客户端抛出的异常是The underlying connection was closed: The connection was closed unexpectedly.
奇怪的是,由于DataContractSerializer无法在连接的服务器端序列化,因此触发了此异常。当枚举无法序列化时提早失败或明显抛出
我宁愿有更多的东西有用扔我,更重要的早些时候,在服务器端运行,但也许编译器警告......
WCF服务合同
[ServiceContract]
public interface IDtoService
{
[OperationContract]
MyDto GetData(int value);
}
public enum Rating
{
None = 0,
NotSet = 1,
Somevalue = 34
}
[DataContract]
public class MyDto
{
Rating _rate;
[DataMember]
public Rating Rating
{
get { return _rate; }
set
{
_rate = value;
}
}
}
服务实施
public class DtoService : IDtoService
{
public MyDto GetData(int value)
{
var dto = new MyDto { Rating = (Rating) 42 }; // not in ENUM!
return dto;
}
}
客户
var cl = new DtoServiceClient.DtoServiceClient();
var tada = cl.GetData(1); // connection closed exception
要具备实际抛出的异常,我不得不确定停用“启用仅我的代码”中的调试选项VS2010和例外对话框。启用已投入“公共语言运行时例外”
随着即设置了宝贵的例外是:
SerializationException
枚举值“42”是类型 “WcfService1.Rating”无效且无法被序列化。确保 必要枚举值都存在,并且都标有 EnumMemberAttribute属性,如果该类型有DataContractAttribute 属性
这是以调试器变得非常嘈杂的所有其他类型抛出的异常的费用是AFAIK能被忽略。
我该如何尝试让这个异常抛出没有噪音?
有什么我可以调整或添加在WCF管道?
一个可能的解决方案,早期与返工的成本无法在枚举成员的制定者增加额外的断言:
Debug.Assert(Enum.IsDefined(typeof(Rating), value),"value is not valid for this enum");
另一种我尝试了将希望一个警告,可能会合同被生产。我找不到比基本上Debug.Assert的副本更好的东西。
System.Diagnostics.Contracts.Contract.Assert(Enum.IsDefined(typeof(Rating), value));
有一个选项可以让编译器发出这张支票对我来说还是有另一种我不知道的?
(我也试图与不期待它成为succeful使check for arithmetic overflow/underflow
编译)
CodeContracts并发出警告,(你必须enble隐枚举写的义务),虽然这并不能真正帮助
实际值可能不是在该枚举值
此行为是在VS2010/.NET 4.0上下文中定义的范围内。
在我看来,合同断言是最好的,你可以做,而不尝试扩展WCF序列化行为(它可以像牦牛一样毛茸茸)。 –
@SixtoSaez经过深入挖掘,我认为你的建议是现在最实用的。我不想修饰一头牦牛... – rene