Pregunta

I have the following simple code in an ApiController:

public Version Get()
{
  var version = new System.Version(1, 1, 0, 0);
  return version;
}

which results in the following:

json

{"_Major":1,"_Minor":1,"_Build":0,"_Revision":0}

xml

<Version xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/System">
  <_Build>0</_Build>
  <_Major>1</_Major>
  <_Minor>1</_Minor>
  <_Revision>0</_Revision>
</Version>

Please note the properties are preceded with an _. Looking at the class definition of Version all those properties are Getters only, which I suspect has something to do with why the serialization is adding the _. I also tried to find information here on why this is happening, but all it says that Read-only properties are serialized by default.

The problem is that the underscore is messing up the deserialization on the client and resulting in Version 0.0.0.0.

This is a CLR class, which I can't override, so how can I remove the underscore so it deserializes correctly on the client?

¿Fue útil?

Solución

By default Web API serializes the fields of types that have a [Serializable] attribute (e.g. Version). I'm not a huge fan of it which is why Json.NET doesn't do it by default, but that's what the Web API guys wanted.

This will stop Web API doing it in JSON:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.ContractResolver = new DefaultContractResolver();

Otros consejos

Without changing the whole serializer, you could return a custom object that is mapped with the CLR Version class.

Version numbers shouldn't change too often. I would recommend putting a comment on it so that your future self do not refactor it away.

If you are using the DataContractSerializer, try this:

config.Formatters.XmlFormatter.SetSerializer(myType, new DataContractSerializer(myType, new DataContractSerializerSettings() { SerializeReadOnlyTypes = true });

Otherwise, make sure JSON.NET is up to date. It shouldn't have any difficulties serializing Read-Only properties.

I've tested with JSON.NET and it seems to pickup the fields that are named like your output and avoid the public properties altogether.

As a temporary solution, I would duplicate the object and return it so to better control serialization.

Latest JSON.NET and MVC binaries are giving the same results. If you set up a console app and use JSON.NET to serialize, you get the expected (no underscores) version. You could try fidgeting about with the media type formatters and serializers, but to be honest, I'd just create a value object to wrap Version and be done with it.

I also tried creating a value object with read only properties, and also field backed properties with no setters. It all serialized without underscores. Must be something in the Version class itself.

If you want a quick workaround, here is one

public object  Get()
    {
        var version = new System.Version(1, 2, 3, 4);
        return new
        {
            version.Build,
            version.Major,
            version.Minor,
            version.Revision
        };
    }

Sorry that I can't help you with this issue. I had something similar in different case. All I can recommand you is to use the

  1. String.Replace('_',string.Empty());
  2. deserialize it.

I hope it will help.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top