12

I am using .NET 4.5.1 for my WCF service, and .NET 4.0 for a client windows service application.

In the Data Contract, there is a DataMember of type DateTimeOffset? (a nullable DataTimeOffset).

When I Add Service Reference to the WCF service, it thinks that DateTimeOffset? is a complex type. In other words, it doesn't think it's a System.DateTimeOffset?, it thinks it's a ServiceReference1.DateTimeOffset?

How do I fix this?

Here's what I've tried so far:

  1. Create the most simple example solution that demonstrates this. Unfortunately I couldn't recreate the issue, so it must be something unique to my configuration.

  2. Annotate the DataContract class with [KnownType(typeof(DateTimeOffset?))]. Unfortunately this didn't do anything.

  3. Check "Reuse types in referenced assemblies". This had the effect of the "ServiceReference1" object not being available at all in the Console Application.

Anyone have any other ideas on how to fix this?

Thank you.

BlueSky
  • 1,449
  • 1
  • 16
  • 22
  • What does your client solution look like? Are you including the Service assemblies in your test client? – dblood Jun 11 '14 at 19:41
  • @dblood, thanks for the reply. Yes, that's the strange thing. I have the Data Contract in its own project (class library), which is referenced by both the WCF project and the Console Application project. – BlueSky Jun 11 '14 at 20:21
  • Ok, that's good. We've employed that exact type of solution before. Can post a screen shot of the solution explorer for the client? – dblood Jun 11 '14 at 20:23
  • 1
    You write that the client thinks it is a type `ServiceReference1.DataTimeOffset?` (note the second **a** in *Data*). I assume that is a spelling error only in this question? Or could there be some naming error in the code that has somehow been able to avoid throwing an error? – Kjartan Jul 24 '15 at 16:28
  • @Kjartan fixed typo, thank you – BlueSky Jan 03 '19 at 03:51

3 Answers3

1

You're on the right track with KnownType.

In order to achieve your goal, you cannot use "Add Service Reference". Instead, your client application must have a reference to your [ServiceContract] class. Then, you can directly invoke the service using a ChannelFactory.

Server Code:

using System;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace Server
{
    public class Service : IService
    {
        public ReturnContract GetOffset()
        {
            return new ReturnContract { Offset = new DateTimeOffset(DateTime.Now) };
        }
    }

    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        ReturnContract GetOffset();
    }

    [DataContract]
    [KnownType(typeof(DateTimeOffset))]
    public class ReturnContract
    {
        [DataMember]
        public DateTimeOffset? Offset { get; set; }
    }
}

Client Code

using Server;
using System;
using System.ServiceModel;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            var cf = new ChannelFactory<Server.IService>("endpoint");
            var service = cf.CreateChannel();
            ReturnContract c = service.GetOffset();

            Console.WriteLine(c.Offset);
            Console.ReadLine();
        }
    }
}
Dan Ling
  • 2,965
  • 2
  • 29
  • 43
1

That can happens when either your data contracts projects is not properly builded or you not select to reuse library that contain DateTimeOffset and Nullable<> - mscorlib and/or your data contract project.

So make sure that:

  1. Data contracts project target framework is not greater than .NET Framework 4.0. Because .NET Framework is not forward compatable. Reference to it from client project must not be marked with warning sign:
    Broken reference in client library
  2. Data contracts project is builded
  3. Both mscorlib and your data contracts project are in the reference list which types need to be reused or you choose to reuse type in all referenced assemblies: Service reference configuration dialog window
Community
  • 1
  • 1
Leonid Vasilev
  • 11,910
  • 4
  • 36
  • 50
0

You're definitely going to have to specify "Reuse types in referenced assemblies" to get the behavior you are looking for.

The question then becomes, what is causing your service to not be available in your Console application. I would guess that your solution is not quite setup correctly, but I would need more details. A screen shot of the solution containing the console application would be ideal.

Did you add your service reference to the Console App project or a different project?

dblood
  • 1,758
  • 17
  • 21