Programming is fun!
I have created my own nullable class implementation as follows:
[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();
}
}
Now in my WCF service when I create function which uses List of my custom nullable types,
[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))
};
}
}
I get following issue when above function gets called:
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.
Help appreciated
I am using 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>
EDIT:
It works with [XmlSerializerFormat] as long as you simply use Nullable<DateTime>, but NOT your implementation of Nullable<T>. So, the DataContractSerializer is giving your Nullable<T> implementation a pass, but the XmlSerializer is not.
Put another way, you have two options:
1) use DataContractSerializer + your Nullable<T> implementation;
2) use XmlSerializer + Nullable<DateTime>.
IService:
[ServiceContract]
[XmlSerializerFormat]
public interface IService1
{
[OperationContract]
List<Nullable<DateTime>> NullTest();
}
Service:
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))
};
}
}
Client:
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);
}
}
}

It works as long as you properly decorate your Nullable<T> with [DataContract] and [DataMember].

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();
}
}
Service:
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))
};
}
}
Client:
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With