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

Creating custom Nullable class implementation in WCF

编程很有趣!

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

[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))
        }; 
    }
}

调用上述函数时出现以下问题:

Managed Debugging Assistant 'FatalExecutionEngineError' has detected a problem in 'C:\Program Files (x86)\IIS Express\iisexpress.exe'.

Additional information: The runtime has encountered a fatal error. The address of the error was at 0x5bd1399e, on thread 0x2568. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.

感谢帮助

我正在使用 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>

编辑:

只要您简单地使用 Nullable<DateTime>,它就可以与 [XmlSerializerFormat] 一起使用,而不是 您对 Nullable<T> 的实现。因此,DataContractSerializer 让您的 Nullable<T> 实现通过,但 XmlSerializer 则不然。

换句话说,你有两个选择:

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

2) 使用XmlSerializer + Nullable<DateTime>.

I服务:

[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);
        }
    }
}


只要你用 [DataContract][DataMember] 正确装饰你的 Nullable<T> 它就可以工作。

I服务:

[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();
    }
}