Data Contract Known Types and a set of interfaces inheriting each other
Asked Answered
T

3

8

I develop (rewrite onto WCF) a file parsing web service accepting string[] and returning ISection[] but actually this is a set of nested interfaces:

namespace Project.Contracts // Project.Contracts.dll
{
    public interface ISection { }

    public interface ISummarySection : ISection { }

    public interface IDataSection : ISection { }
}

and classes:

namespace Project.Format.A // Project.Format.A.dll
{
    [DataContract]
    public class SummarySectionFormatA : ISummarySection { }

    [DataContract]
    public class DataSectionFormatA : IDataSection { }
}

Service interface and its implementation:

[ServiceContract]
public interface IService // Project.Contracts.dll
{
    ISection[] Parse(string format, string[] data);
} 

[ServiceKnownType(typeof(SummarySectionFormatA))] // tried this also
[ServiceKnownType(typeof(DataSectionFormatA))]
public class Service : IService // Project.Service.dll
{
    public ISection[] Parse(string format, string[] data)
    {
        return Factory.Create(format).Parse(data);
    }
}

I tried to configure declaredTypes on both server and clients:

<system.runtime.serialization>
  <dataContractSerializer>
    <declaredTypes>
      <add type="Project.Contracts.ISumarySection, Project.Contracts">
        <knownType type="Project.Format.A.SummarySectionFormatA, Project.Format.A" />
      </add>
      <add type="Project.Contracts.IDataSection, Project.Contracts">
        <knownType type="Project.Format.A.DataSectionFormatA, Project.Format.A" />
      </add>
    </declaredTypes>
  </dataContractSerializer>
</system.runtime.serialization>

But still get the same error:

"Type 'DataSectionFormatA' with data contract name 'DataSection:http://schemas.example.com/Parse' is not expected.

or

The underlying connection was closed: The connection was closed unexpectedly.

I can't decorate interfaces with KnownTypeAttribute because Contracts projects doesn't reference Format projects, and referencing breaks the design. That's why I want to use config.

Thallus answered 30/6, 2012 at 8:26 Comment(1)
Can you post your service operation contracts pleaseBosomy
T
0

Trying to make this working:

[KnownType("GetKnownType")]
public class Section
{
    static Type[] GetKnownType()
    {
        return new[]
        {
            Type.GetType("Project.Format.A.DataSectionFormatA, Project.Format.A")
        };
    }
}

but seems that both server and client must reference Project.Format.A.dll to make it working (method do not return null)

Thallus answered 2/7, 2012 at 7:3 Comment(0)
C
2

Take a look at the code below

[ServiceContract]
[ServiceKnownType(typeof(SummarySectionFormatA))]
[ServiceKnownType(typeof(DataSectionFormatA))]
public interface IService {}

public class Service : IService {}
Counterclaim answered 30/6, 2012 at 13:18 Comment(1)
Ok, I got it. So you suggest to decorate the interface (service contract) but no the implementation. But as I mentioned in the bottom of my question, I don't want to do it, because the interface is placed into the Contracts.dll which references no other in-project dlls, and it can't due preventing a circular reference. I want to use a config.Thallus
N
1

I believe you should change your implementation a little... have a look at this question and see if it helps.

Numberless answered 2/7, 2012 at 7:23 Comment(5)
Right. My main question is why doesn't config works. Seems because project is not referenced (what I want to avoid) and Type.GetType() returns null. Need to change implementation indeed.Thallus
Correct! Problem is Service is depending on something which is unknown... Also I want to question the use of Interface for Data Contracts, why do you intend to abstract that. Would recommend to make it as concrete or think on that angle as well.Numberless
It was the initial design and it was working fine as a part of a web app. Now I'm separating parsing logic from the app into a dedicated web (WCF) service, so trying to do that without major design changes first.Thallus
Do share the design you finally concluded with.Numberless
Both config and attribute ways work for me with condition to reference all type-to-know projects to both server and client.Thallus
T
0

Trying to make this working:

[KnownType("GetKnownType")]
public class Section
{
    static Type[] GetKnownType()
    {
        return new[]
        {
            Type.GetType("Project.Format.A.DataSectionFormatA, Project.Format.A")
        };
    }
}

but seems that both server and client must reference Project.Format.A.dll to make it working (method do not return null)

Thallus answered 2/7, 2012 at 7:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.