在WCF中创建自定义Nullable类实现

时间:2017-01-19 13:21:17

标签: c# .net wcf xml-serialization iis-express

编程很有趣!

我创建了自己的可空类实现,如下所示:

[DataContract]
public class Nullable<T> where T : struct
{
    public Nullable()
    {
    }

    internal T value;

    [DataMember]
    public bool HasValue { get; set; }

    [DataMember]
    public T Value
    {
        get
        {
            if (!this.HasValue)
                throw new Exception("Property have  no value");
            return this.value;
        }
        set
        {
            this.value = value;
            this.HasValue = true;
        }
    }

    public Nullable(T value)
    {
        Value = value;
    }

    public T GetValueOrDefault()
    {
        return this.value;
    }

    public T GetValueOrDefault(T defaultValue)
    {
        if (!this.HasValue)
            return defaultValue;
        return this.value;
    }

    public override bool Equals(object other)
    {
        if (!this.HasValue)
            return other == null;
        if (other == null)
            return false;
        return this.value.Equals(other);
    }

    public override int GetHashCode()
    {
        if (!this.HasValue)
            return 0;
        return this.Value.GetHashCode();
    }

    public override string ToString()
    {
        if (!this.HasValue)
            return "";
        return this.Value.ToString();
    }
}

现在在我的WCF服务中,当我创建使用List我的自定义可空类型的函数时,

[ServiceContract]
[XmlSerializerFormat]
public interface IService
{
    [OperationContract]
    List<Nullable<DateTime>> NullTest();
}

public class MyService : IService
{
    public List<Nullable<DateTime>> NullTest()
    {
        return new List<Nullable<DateTime>>()
        {
            new Nullable<DateTime>(DateTime.Now),
            new Nullable<DateTime>(DateTime.Now.AddDays(2))
        }; 
    }
}

当调用上面的函数时,我遇到以下问题:

  

托管调试助手&#39; FatalExecutionEngineError&#39;已经检测到了   问题在C:\ Program Files(x86)\ IIS Express \ iisexpress.exe&#39;。

     

其他信息:运行时遇到致命错误。该   错误的地址是0x5bd1399e,在线程0x2568上。错误   代码是0xc0000005。此错误可能是CLR或中的错误   用户代码的不安全或不可验证部分。这个的常见来源   错误包括COM-interop或PInvoke的用户封送错误   可能会破坏堆栈。

帮助表示赞赏

我正在使用BasicHttpBinding

  <service name="MyService">
    <endpoint 
      address="" 
      binding="basicHttpBinding"
      name="BasicHttpEndpoint"
      bindingConfiguration=""
      contract="IMyService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>

1 个答案:

答案 0 :(得分:2)

修改

只要您使用[XmlSerializerFormat],而不是{strong>您的实施 Nullable<DateTime>,它就可以与Nullable<T>一起使用。因此,DataContractSerializer为您的Nullable<T>实施提供了通过,但XmlSerializer却没有。

换句话说,您有两种选择:

1)使用DataContractSerializer +您的Nullable<T>实施;

2)使用XmlSerializer + Nullable<DateTime>

<强> IService:

[ServiceContract]
[XmlSerializerFormat]
public interface IService1
{
    [OperationContract]
    List<Nullable<DateTime>> NullTest();
}

<强>服务

public class Service1 : IService1
{
    public List<Nullable<DateTime>> NullTest()
    {
        return new List<Nullable<DateTime>>()
        {
            new Nullable<DateTime>(DateTime.Now),
            new Nullable<DateTime>(DateTime.Now.AddDays(2))
        };
    }
}

<强>客户端:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Service1Client client = new Service1Client();

            ArrayOfDateTime result = client.NullTest();

            foreach (DateTime dt in result)
                Console.WriteLine(dt);

            Console.ReadLine();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

enter image description here

只要您使用Nullable<T>[DataContract]正确装饰[DataMember],就会有效。

enter image description here

<强> IService:

[ServiceContract]
public interface IService1
{

    [OperationContract]
    List<Nullable<DateTime>> NullTest();
}

[DataContract]
public class Nullable<T> where T : struct
{
    public Nullable()
    {
    }

    internal T value;

    [DataMember]
    public bool HasValue { get; set; }

    [DataMember]
    public T Value
    {
        get
        {
            if (!this.HasValue)
                throw new Exception("Property have  no value");
            return this.value;
        }
        set
        {
            this.value = value;
            this.HasValue = true;
        }
    }

    public Nullable(T value)
    {
        Value = value;
    }

    public T GetValueOrDefault()
    {
        return this.value;
    }

    public T GetValueOrDefault(T defaultValue)
    {
        if (!this.HasValue)
            return defaultValue;
        return this.value;
    }

    public override bool Equals(object other)
    {
        if (!this.HasValue)
            return other == null;
        if (other == null)
            return false;
        return this.value.Equals(other);
    }

    public override int GetHashCode()
    {
        if (!this.HasValue)
            return 0;
        return this.Value.GetHashCode();
    }

    public override string ToString()
    {
        if (!this.HasValue)
            return "";
        return this.Value.ToString();
    }
}

<强>服务

public class Service1 : IService1
{
    public List<Nullable<DateTime>> NullTest()
    {
        return new List<Nullable<DateTime>>()
        {
            new Nullable<DateTime>(DateTime.Now),
            new Nullable<DateTime>(DateTime.Now.AddDays(2))
        };
    }
}

<强>客户端:

class Program
{
    static void Main(string[] args)
    {
        Service1Client client = new Service1Client();

        NullableOfdateTime[] result = client.NullTest();

        foreach (NullableOfdateTime ndt in result)
            Console.WriteLine(ndt.Value);

        Console.ReadLine();
    }
}