早期的失败或明确抛出时,一个枚举不能序列 [英] Fail early or clearly throw when an enum cannot be serialized

查看:151
本文介绍了早期的失败或明确抛出时,一个枚举不能序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在哪里WCF服务返回一个DataContract与具有无效值(int类型的枚举类型不存在)在客户端的基础连接是抛出的异常枚举成员场景关闭:连接被意外关闭结果
奇怪的是这个异常被触发,因为DataContractSerializer的不能在连接的服务器端序列化。

In the scenario where a WCF service returns a DataContract with an enum member that has an invalid value (an int not present in the Enum type) the thrown exception on the client side is The underlying connection was closed: The connection was closed unexpectedly.
Strangely enough this exception is triggered because the DataContractSerializer cannot serialize at the serverside of the connection.

我宁愿有更多的东西有用扔我,更重要的早些时候,在服务器端运行,但也许编译器警告...

I would rather have something more usefull thrown at me and more important earlier, at runtime on the serverside but maybe a compiler warning...

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和例外对话框启用时抛出的通用语言运行时例外

To have the actual exception thrown I had to disbale 'enable just my code' in the debug options VS2010 and in the Exceptions dialog enable Thrown for 'Common language Runtime exceptions'

通过该设置宝贵的例外是:

With that settings the valuable exception is:

SerializationException结果
枚举值'42'是输入
'WcfService1.Rating'无效,不能被序列化。确保
必要枚举值存在并标有
EnumMemberAttribute属性,如果该类型有DataContractAttribute
属性。

SerializationException
Enum value '42' is invalid for type 'WcfService1.Rating' and cannot be serialized. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute

这正值调试器变得非常嘈杂的所有其他类型抛出的异常的AFAIK可以忽略不计的成本。

This comes at the cost that the debugger gets very noisy about all other kinds of thrown exceptions that AFAIK can be ignored.

我能尝试有此异常无噪音抛出?

有什么我可以调整或添加在WCF管道?

一个可行的办法失败早返工的成本在枚举成员设置器增加一个额外的断言:

One possible solution to fail early with the cost of rework is adding an extra Assert in the setter of the enum member:

Debug.Assert(Enum.IsDefined(typeof(Rating), value),"value is not valid for this enum");

这是另一种我试过,希望警告可能会产生被加入合同。我找不到任何东西比Debug.Assert的基本上副本更好。

An alternative I tried was adding a Contract in the hope a warning could be produced. I couldn't find any thing better than basically a copy of the Debug.Assert.

System.Diagnostics.Contracts.Contract.Assert(Enum.IsDefined(typeof(Rating), value));



是否有一个选项,编译器发出这张支票对我来说还是有替代我不知道呢?结果
(我也试图与编译检查算术溢出/下溢没有它期待已启用是succeful)

Is there an option to have the compiler emit this check for me or is there an alternative I'm not aware of?
(I also tried to compile with the check for arithmetic overflow/underflow enabled without expecting it to be succeful)

CodeContracts并发出警告,(你必须enble隐枚举写的义务),虽然这并不能真正帮助

CodeContracts does emit a warning, (you have to enble Implicit Enum write obligations) though that does not really help

实际值可能不会在此枚举值

The actual value may not be in the range defined for this enum value

这所定义的范围行为是在VS2010 / .NET 4.0环境。

This behavior is in a VS2010/.Net 4.0 context.

推荐答案

您可以做一些事情。

在WCF端,使用 IncludeExceptionDetailInFaults (或者使用一个的 ServiceBehavior 属性或在你的的app.config )。这将使WCF发送详细的例外到客户端。请注意,这被认为是不安全的设置,因为它暴露了服务器堆栈跟踪到客户端,所以你应该只在开发过程中使用它。对于生产,你应该使用一个WCF错误处理程序来记录所有服务错误(或打开WCF跟踪)。

On the WCF side, use IncludeExceptionDetailInFaults (either using a ServiceBehavior attribute or in your app.config). This will make WCF send detailed exceptions to the client. Note this is considered an 'unsafe' setting since it exposes server stack traces to the client side, so you should only use that during development. For production, you should use a WCF error handler to log all service errors (or turn on WCF tracing).

如果你想使用代码契约期间赶上这个错误编译时间您可以使用对象不变:

If you want to use Code Contracts to catch this error during compile time you can use object invariants:

public class MyDto
{
    public Rating Rating { get; set; }

    [ContractInvariantMethod]
    void Invariant()
    {
        Contract.Invariant(Enum.IsDefined(typeof(Rating), Rating));
    }
}

如果您启用静态分析,您将收到一条警告在这条线:

If you enable static analysis, you will receive a warning on this line:

new MyDto {  Rating = (Rating) 42 };

这篇关于早期的失败或明确抛出时,一个枚举不能序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆