2016-09-25 12 views
1

В этом простом примере я пытаюсь получить объект, сериализованный как JSON из службы Web Api 2 + OData v4. Контроллер имеет связанную функцию Test, возвращающую массив annon. объекты.Web Api 2 с OData v4 - Связанная функция, возвращающая сложный объект

public class ProductsController : ODataController 
{ 
    [HttpGet] 
    public IHttpActionResult Test(int key) 
    { 
     var res = new[] 
     { 
      new { Name = "a", Value = new[] { 1, 2, 3 } }, 
      new { Name = "b", Value = new[] { 2, 4, 5 } } 

      // this also produces same result 
      // new { Name = "a", Value = "c" }, 
      // new { Name = "b", Value = "c" } 
     }; 

     return this.Ok(res); 
    } 
} 

Edm построен этот кусок кода:

ODataModelBuilder builder = new ODataConventionModelBuilder(); 

builder.EntitySet<Product>("Products"); 
var productType = builder.EntityType<Product>(); 

var f = productType.Function("Test").Returns<object>(); 

когда я делаю запрос к сервису (например, http://localhost:9010/odata/Products(33)/Default.Test.) Я получаю странный ответ - массив из двух пустых объектов, как это:

{ 
    "@odata.context": "http://localhost:9010/odata/$metadata#Collection(System.Object)", 
    "value": [ 
    {}, 
    {} 
    ] 
} 

в моем реальном приложении я возвращаю объект сериализуется в строку JSON с преобразователем Json Newtonsoft в - что работает хорошо, но эта проблема до сих пор беспокоит меня. Я подозреваю, что это связано с сериализатором по умолчанию для OData, но мне непонятно, как его настроить.

Итак, можно ли настроить параметр возвращаемой функции edm таким образом, чтобы я мог правильно сериализовать сложный объект?

Спасибо!

+0

Я не думаю, что одата предназначена для работы с остроумием h анонимного типа вроде этого, но я недостаточно уверен, чтобы опубликовать это как ответ!Я думаю, вам нужно определить тип, добавить его в построитель модели (и изменить Returns () из «объекта» на ваш новый тип), а затем создать экземпляр этого типа, где вы в настоящее время создаете свой анонимный тип. .. Мне кажется, что odata возвращает «объект», который вы ему сказали, но он не получил определение сказать больше, чем «здесь есть объект». – lukkea

+0

Я забыл упомянуть - даже если я объявляю какой-то тип, а затем. Возвращает (), результат такой же: \ –

ответ

2

Как сказал lukkea, OData не предназначен для работы с анонимными типами.
Обратите внимание, что в вас WebApiConfig вы должны изменить «Возвраты» на «ВозвратКоллекция», если вы возвращаете коллекцию.

В любом случае, допустим, вы написали следующее.

return this.Ok(Newtonsoft.Json.JsonConvert.SerializeObject(res)); 

var f = productType.Function("Test").Returns<string>(); 

Вы получите обратно следующее:

{ 
    "@odata.context": "http://localhost/Test/odata/$metadata#Edm.String", 
    "value": 
     "[ 
      {\"Name\":\"a\",\"Value\":[1,2,3]}, 
      {\"Name\":\"b\",\"Value\":[2,4,5]} 
     ]" 
} 

Обратите внимание, что есть еще 2 элементы в массиве, но на этот раз они не пустуют.
Поскольку OData не знал тип возврата в предыдущем примере, он возвращает 2 объекта без значений.

У вас есть 2 варианта.

  1. Возврат анонимного типа в виде сериализованной строки json и последующего десериализации этого json на стороне клиента.
  2. Создайте класс и верните этот тип.

Вариант 1

// ON SERVER 
return this.Ok(Newtonsoft.Json.JsonConvert.SerializeObject(res)); 

var f = productType.Function("Test").Returns<string>(); 

// ON CLIENT 
string jsonString = odataContext.Products.ByKey(33).Test().GetValue(); 
var objectList = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(jsonString); 

string firstObjectName = objectList[0].Name; 

Вариант 2

// ON SERVER 
public class TestObject 
{ 
    public string Name { get; set; } 
    public List<int> Integers { get; set; } 
} 

var res = new List<TestObject> 
{ 
    new TestObject { Name = "a", Integers = new List<int> { 1, 2, 3 } }, 
    new TestObject { Name = "b", Integers = new List<int> { 2, 4, 5 } } 
}; 

return this.Ok(res); 

var f = productType.Function("Test").ReturnsCollection<TestObject>(); 

Если вы хотите, чтобы вернуть человека с дополнительным свойством, что не сильно типизированных то вы хотите ODataOpenType

+0

Я бы упомянул, что getter и setter в определении класса TestObject не являются необязательными. – Matt

 Смежные вопросы

  • Нет связанных вопросов^_^