1
votes

I've been reading the documentation for protobuf-net attributes, but i'm not well-versed with protobuf specifications.

I'm using it in a MVC project and during de-serialization, the DbGeography is empty.

Class

public class Foo
{
    [ProtoMember(1)]
    public int Id { get; set; }        
    [ProtoMember(2, AsReference = true)]
    public DbGeography Location { get; set; }
}

This is what my class looks like currently, i've tried using DynamicType & IsRequired, anyway all didn't work. Rather than trying to guess/mix & match, i'm hoping that someone has been doing something similar.

The nearest thing i've seen while looking around is this project that have a custom reader and writer that uses protobuf for spatial data types, but it's a custom class.

Update

public class Foo
{
    [ProtoMember(1)]
    public int Id { get; set; }        
    [ProtoMember(2, DynamicType= true)] //<-- this works
    public DbGeography Location { get; set; }
}

But i'm still wondering what's the best way to label these members, like a performance vs size trade-off

Update 2

[ProtoContract]
public class Foo
{
    [ProtoMember(1)]
    public int Id { get; set; }
    public string Address { get; set; }
    [ProtoMember(2, AsReference = true)] 
    public DbGeography Location { get; set; }
    [ProtoMember(8, AsReference = true)] //<-- What is the cost of using this for List<Bar>? since im using a non-primitive type
    public List<Bar> Bars { get; set; }
}
1

1 Answers

0
votes

Re the update:

[ProtoMember(2, DynamicType= true)] //<-- this works

I do not advise that. As for the correct thing to do; I would recommend a surrogate type:

[ProtoContract]
sealed class DbGeographyPoco
{
    [ProtoMember(1)]
    public string Value { get; set; }

    public static implicit operator DbGeographyPoco(DbGeography value)
    {
        return value == null ? null : new DbGeographyPoco {
            Value = value.WellKnownValue.WellKnownText };
    }
    public static implicit operator DbGeography(DbGeographyPoco value)
    {
        return value == null ? null : DbGeography.FromText(value.Value);
    }
}

which you can then register somewhere during app startup via:

RuntimeTypeModel.Default.Add(typeof(DbGeography),false)
   .SetSurrogate(typeof(DbGeographyPoco));