我正在尝试克服WCF和枚举的问题,我正在尝试将对象从服务器传递到包含枚举的客户端(或其他服务器).枚举以1开头,故意.枚举初始化时以及在其中定义值时,一切都很顺利,但是当它未在枚举中定义时,我得到了这个非常好的(并且非常具有描述性(...))错误消息:
"底层连接已关闭:连接意外关闭."
我试图实现的是当我得到这个场景时,无论是从数据库中的损坏数据(无论如何都被转换为枚举,这是非常奇怪的),或者当开发人员忘记在启动对象时设置枚举值时,要获得有意义的消息,例如"枚举值无效,请键入:{0},值:{1}".
我试图在类的枚举和getter中使用"Enum.IsDefined",并将有意义的异常抛给客户端(或其他服务器),但仍然出现"连接关闭"错误(当允许调试服务器我得到了有意义的消息,但仅在服务器端).
这是enum setter和getter的片段:
private TestEnum m_TestEnum;
[DataMember]
public TestEnum TestEnum
{
get
{
if (Enum.IsDefined(typeof(TestEnum), m_TestEnum))
{
return m_TestEnum;
}
else
{
throw new ApplicationException("Enum value is not valid: " + m_TestEnum);
}
}
set
{
if (Enum.IsDefined(typeof(TestEnum), value))
{
m_TestEnum = value;
}
else
{
throw new ApplicationException("Enum value is not valid: " + value);
}
}
}
Run Code Online (Sandbox Code Playgroud)
从0开始枚举(带有"未知"值)不够好,因为我仍然可以获得枚举中不存在的值.我可以结合两种解决方案,我检查"IsDefined"并将枚举设置为"未知"值,但仍然 - 这不是理想的解决方案,因为我们想知道这些情况,以便在开发周期中解决它们.
你说什么?谢谢,Nir.
通过WCF发送枚举时,将发送枚举值的字符串表示形式,而不是数字值.这允许双方将相同的枚举标签映射到不同的数字.
如果发送的标签未被收件人理解,则该频道将被关闭.我相信这会延伸到未定义的枚举值(它看起来像你正在迎合它.)
因此,仅仅因为枚举标签在发件人方面是有效的并不意味着客户端必然会理解它.
您是否在发件人和收件人之间共享相同的类定义?
要进一步调试此问题,您应该在客户端和服务器中启用服务跟踪(这对于许多令人沮丧的WCF问题都是如此.)它将帮助您确定问题的根源,否则您没有任何指示.
将以下XML添加到App.config(在客户端和服务器上):
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "WcfTrace.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
Run Code Online (Sandbox Code Playgroud)
添加此配置后,您将创建一个.svclog
可以使用服务跟踪查看器工具查看的文件.此日志包含有关发生的所有事件的大量信息,包括警告和错误.
请注意,生成的日志文件可能会非常大,因此在完成调试后,请务必删除或注释掉此配置部分.
请注意,您可以为要在线路上使用的枚举成员指定不同的字符串值.
例如,以下两个枚举在WCF上是等效的:
public enum CarCondition
{
New,
Used,
Rental,
[NonSerialized]
Lost
}
[DataContract(Name = "CarCondition")]
public enum CarConditionWithDifferentNames
{
[EnumMember(Value = "New")]
BrandNew,
[EnumMember(Value = "Used")]
PreviouslyOwned,
[EnumMember]
Rental
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处阅读有关在WCF上使用枚举的更多信息.