Ryan Leach
Ryan Leach

Reputation: 4470

How can you remove the type attribute from a KnownType in a DataContract class?

Is it possible to use the KnownType's class name as the tag, rather then the parent classes? e.g.

This is an excerpt from a larger DataContract xml file,

[DataContract (Namespace = "projectNamespace")]
[KnownType(typeof(Warning)), KnownType(typeof(Error))]
public abstract class Message
{
    protected Message(LogLevel logLevel, int percentUsed, string message)
    {
        this.LogLevel = logLevel;
        this.LogMessage = message;
        this.Percent = percentUsed;
    }

    internal readonly LogLevel LogLevel;
    [DataMember] internal readonly int Percent;    
    [DataMember] internal readonly string LogMessage;
}

[DataContract (Name="Warning", Namespace = "projectNamespace")]
internal sealed class Warning : Message
{
    public Warning(int percentUsed, string message) : base(LogLevel.Warn, percentUsed, message)
    {
    }
}

[DataContract(Name = "Error", Namespace = "projectNamespace")]
internal sealed class Error : Message
{
    public Error(int percentUsed, string message) : base(LogLevel.Error, percentUsed, message)
    {
    }
}

public enum LogLevel
{
    Warn, Error
}

What I saw:

<messages>
  <Message i:type="Warning">
    <PercentUsed>75</PercentUsed>
    <LogMessage>75% used</LogMessage>
  </Message>
  <Message i:type="Error">
    <PercentUsed>100</PercentUsed>
    <LogMessage>0% remaining</LogMessage>
  </Message>
</messages>

Expected:

<messages>
  <Warning>
    <PercentUsed>75</PercentUsed>
    <LogMessage>75% used</LogMessage>
  </Warning>
  <Error>
    <PercentUsed>100</PercentUsed>
    <LogMessage>0% remaining</LogMessage>
  </Error>
</messages>

Note how the Message has an annoying i:type="Error" rather then just being a <Error>

Upvotes: 0

Views: 280

Answers (1)

Sergey A Kryukov
Sergey A Kryukov

Reputation: 933

What you implemented is good. You've achieved polymorphism for a single object of derived runtime types.

What you think you want is wrong. What looks redundant to you is absolutely essential and informative. In <Message i:type="Warning">, the tag Message indicates the abstract base type. The attribute value Warning indicates the instance runtime type derived from Message. If the XML did not contain the name of the base class Message, the Code Project mechanism would not even search for the set of known types. How the code would be supposed to “know” where to look for them?

However, the attempts to “improve” Data Contract XML by shortening the “obvious” (no, it is not obvious at all) is the entire phenomenon. Why any ad hoc approach here? Why do you think this kind of mess can improve anything? I cannot understand you guys.

You already have done a good job on your contract and produced right result, so I suggest you accept my answer and close the issue.

Upvotes: 1

Related Questions