0

I am trying to use [Serializable] attribute with a PetaPoco Entity so it can be stored in a REDIS Cache.

Adding the [Serializable] attribute to the PetaPoca Entity class allows it to be cached with a REDIS Caching provider but then changes the way the WebAPI serializes the Entity to JSON which breaks.

Is there a way to specify how the WebAPI serializes the object to JSON?

Examples below, for specifics this is within the DAL2 for DNN and using the https://github.com/davidjrh/dnn.rediscachingprovider REDIS Caching Provider for DNN.

DNN DAL2 / PetaPoco Object:

[TableName("sbCurrencyRates")]
//setup the primary key for table
[PrimaryKey("CurrID", AutoIncrement = true)]
//configure caching using PetaPoco
[Cacheable("sbCurrencyRates", CacheItemPriority.Default, 20)]
//scope the objects to the ModuleId of a module on a page (or copy of a module on a page)

[Serializable]
public class CurrRateInfo
{
    public int CurrID { get; set; }
    public string CurrCode { get; set; }
    public double CurrRate { get; set; }
    public DateTime LastUpdate { get; set; }
}

WebApi Controller:

public class RatesController : DnnApiController
{
    [AllowAnonymous]
    [HttpGet]
    public HttpResponseMessage GetRates()
    {
        CurrRatesController crc = new CurrRatesController();
        return Request.CreateResponse(HttpStatusCode.OK, crc.Get());
    }        
}

Thanks in advance.

VDWWD
  • 35,079
  • 22
  • 62
  • 79
JaxUK
  • 53
  • 6

1 Answers1

0

Assuming you are using a fairly recent version of , then the Json.NET serializer is being used to serialize your class. By default Json.NET ignores [Serializable], however it is possible to force it to serialize types with this attribute in the same way that BinaryFormatter does (i.e. by serializing their public and private fields) by setting IgnoreSerializableAttribute on DefaultContractResolver to false. And in fact, asp.net does just this, which globally changes how [Serializable] classes are converted to JSON -- as you are seeing.

To prevent this, your options include the following:

  1. Set IgnoreSerializableAttribute = true globally in asp.net. To do this see ASP.NET Web API and [Serializable] class or Setting IgnoreSerializableAttribute Globally in Json.net.

  2. Mark your class with [JsonObject(MemberSerialization = MemberSerialization.OptOut)]:

    [Serializable]
    [JsonObject(MemberSerialization = MemberSerialization.OptOut)]
    public class CurrRateInfo
    {
    }
    
  3. Annotate your class with [DataContract] and [DataMember] attributes. These take precedence over [Serializable].

    [Serializable]
    [DataContract]
    public class CurrRateInfo
    {
        [DataMember]
        public int CurrID { get; set; }
        [DataMember]
        public string CurrCode { get; set; }
        [DataMember]
        public double CurrRate { get; set; }
        [DataMember]
        public DateTime LastUpdate { get; set; }
    }
    

    Do this if you don't want a direct dependency on Json.NET from your models, and don't want to change the global behavior of asp.net.

dbc
  • 104,963
  • 20
  • 228
  • 340