2016-09-25 36 views
1

在這個簡單的例子中,我試圖讓從網絡API 2 +的OData v4的服務序列化爲JSON對象。控制器綁定函數Test返回一個annon數組。對象。網頁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字符串與Newtonsoft的Json的轉換器對象 - 工作正常,但這個問題仍然困擾着我。我懷疑這與OData的默認序列化程序有關,但我不清楚如何配置它。

那麼,是不是可以配置EDM函數的返回參數在這樣的方式,我會得到正確的序列化複雜的對象?

謝謝!

+0

我不認爲odata是設計用於機智的h這樣的匿名類型,但我沒有足夠的信心發佈這個答案!我認爲你需要定義一個類型,將它添加到模型構建器中(並將返回()從「object」更改爲新定義的類型),然後在當前創建匿名類型的位置創建該類型的實例。 ..在我看來,odata正在返回你所告訴它的「對象」,但它沒有定義可言,而不是「這裏有一個對象」。 – lukkea

+0

我忘了提及 - 即使我聲明瞭某種類型,然後返回(),結果也是一樣的:\ –

回答

2

正如lukkea說,OData的不是設計與匿名類型的工作。
側面說明,在你WebApiConfig你應該如果你正在返回集合改變「返回」到「ReturnsCollection」。

無論如何,讓我們假設你寫了下面。

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

我會提到TestObject類定義中的getter和setter似乎不是可選的。 – Matt