7

I have an OData controller that returns a model containing an Enum property. The default behaviour of Json is to parse Enums to return the value name not its Int value. I create a custom Json Converter that uses the int value (still as a string following OData spec), and specified this Converter on the Global.asax file. The problem is that the OdataController does not use the converter at all.

My question is, am I missing something or doing the configuration wrong for Odata? I know that this works fine with a regular APIController.

The second question (more like an opinion really), I am going on the wrong way using OData? So far using ODataController has proven to be more hassle than worth for my scenario.

Here an example to replicate the problem:

public enum Currency {
    [Display(Name = "British Pound")]
    GBP = 1,
    [Display(Name = "Dollar")]
    USD = 2,
    [Display(Name = "Euro")]
    EUR = 3,
    [Display(Name = "Brazilian Real")]
    BRL = 4
}
public class OrderItem {
    public int Id { get; set; }
    public string Description { get; set; }
    public decimal Amount { get; set; }
    public Enumerators.Currency Currency { get; set; }
}
// api/OrderItem
public class OrderItemController : ApiController{
    public IEnumerable<Models.OrderItem> Get(){
        List<Models.OrderItem> toReturn = new List<Models.OrderItem>();
        toReturn.Add(new Models.OrderItem() {
            Id = 1,
            Description = "Rubiks cube",
            Amount = 10,
            Currency = Models.Enumerators.Currency.GBP
        });
        toReturn.Add(new Models.OrderItem() {
            Id = 1,
            Description = "Risk",
            Amount = 5,
            Currency = Models.Enumerators.Currency.USD
        });
        toReturn.Add(new Models.OrderItem() {
            Id = 1,
            Description = "Ticket to ride",
            Amount = 25,
            Currency = Models.Enumerators.Currency.EUR
        });

        return toReturn;
    }
}
// odata/OrderItems
public class OrderItemsController : ODataController{
    private static ODataValidationSettings _validationSettings = new ODataValidationSettings();

    // GET: odata/OrderItems
    public IHttpActionResult GetOrderItems(ODataQueryOptions<OrderItem> queryOptions)
    {
        List<Models.OrderItem> toReturn = new List<Models.OrderItem>();
        toReturn.Add(new Models.OrderItem() {
            Id = 1,
            Description = "Rubiks cube",
            Amount = 10,
            Currency = Models.Enumerators.Currency.GBP
        });
        toReturn.Add(new Models.OrderItem() {
            Id = 1,
            Description = "Risk",
            Amount = 5,
            Currency = Models.Enumerators.Currency.USD
        });
        toReturn.Add(new Models.OrderItem() {
            Id = 1,
            Description = "Ticket to ride",
            Amount = 25,
            Currency = Models.Enumerators.Currency.EUR
        });

        // return Ok<IEnumerable<OrderItem>>(orderItems);
        return Ok(toReturn);
    }
}

protected void Application_Start(){
    GlobalConfiguration.Configure(WebApiConfig.Register);
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new Helpers.IntEnumConverter());
}

Calling api/orderitem return as expected, Currency is either '1', '2' or '3'.
Calling odata/OrderItems returns the default Json formatter, Currency is either 'GBP', 'USD' or 'EUR'

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
Claiton Lovato
  • 2,382
  • 1
  • 22
  • 23
  • 6
    Json.Net is the default serializer for Web API, but not for OData (surprisingly). OData has its own internal serializer. I believe there are hooks would allow you to replace it with Json.Net, but that is not the default configuration. See [JSON.NET as a WebAPI 2 OData serializer vs ODataMediaTypeFormatter](http://stackoverflow.com/q/20656229/10263) – Brian Rogers Dec 02 '15 at 22:10
  • Thanks @BrianRogers, I was suspecting of something like that. I will test that with MediaTypeFormatter and update here once its resolved. – Claiton Lovato Dec 07 '15 at 14:44

0 Answers0