2013-01-04 167 views
3

我讀過WCF Data Service 5.0 release notes,其中提到了OData Actions(不是服務方法)的實現。實現WCF數據服務OData操作

經過分析tutorials我得出結論,我需要爲自己建立WCF Data Services Action Provider for Entity Framework

該項目只有一個簽入,並且自那時起沒有更新。我認爲它沒有錯誤,但根據統計數據,我不希望太多的客戶羣分享經驗。

您是否知道在.NET中實現OData操作的其他選項?

回答

1

我想你是對的。其基本思路看起來像:

/// <summary> 
/// Invokation helper for Actions in the ReSTful world, this is provided since currently no methods exist to 
/// do this in the Microsoft Services framework that I could find. 
/// </summary> 
/// <typeparam name="InType">The type of the entity to invoke the method against</typeparam> 
public class InvokationHelper<InType, OutType> 
{ 

    /// <summary> 
    /// Invokes the action on the entity passed in. 
    /// </summary> 
    /// <param name="container">The service container</param> 
    /// <param name="entity">The entity to act upon</param> 
    /// <param name="ActionName">The name of the action to invoke</param> 
    /// <returns>OutType object from the action invokation</returns> 
    public OutType InvokeAction(Container container, InType entity, string ActionName) 
    { 
     string UriBase = container.GetEntityDescriptor(entity).SelfLink.AbsoluteUri; 
     string UriInvokeAction = UriBase + "/" + ActionName; 

     Debug.WriteLine("InvokationHelper<{0}>.InvokeAction: {1}", typeof(InType), UriInvokeAction); 

     try 
     { 
      IEnumerable<OutType> response; 

      response = container.Execute<OutType>(
       new Uri(UriInvokeAction), 
       "POST", 
       true 
       ); 
      return response.First(); 
     } 
     catch (Exception e) 
     { 
      throw e; 
     } 
    } 

    /// <summary> 
    /// Invokes the action on the entity passed in. 
    /// </summary> 
    /// <param name="container">The service container</param> 
    /// <param name="entity">The entity to act upon</param> 
    /// <param name="ActionName">The name of the action to invoke</param> 
    /// <returns>An enumeration of OutType object from the action invokation</returns> 
    public IEnumerable<OutType> InvokeActionEnumerable(Container container, InType entity, string ActionName) 
    { 
     string UriBase = container.GetEntityDescriptor(entity).SelfLink.AbsoluteUri; 
     string UriInvokeAction = UriBase + "/" + ActionName; 

     Debug.WriteLine("InvokationHelper<{0}>.InvokeAction: {1}", typeof(InType), UriInvokeAction); 

     try 
     { 
      IEnumerable<OutType> response; 

      response = container.Execute<OutType>(
       new Uri(UriInvokeAction), 
       "POST", 
       true 
       ); 
      return response; 
     } 
     catch (Exception e) 
     { 
      throw e; 
     } 
    } 
} 

}

我敢肯定有很多更優雅的方式來做到這一點。如果你已經寫了任何代碼,我很樂意看到它。我的C#圍繞語言的邊緣(比如創建泛型方法來調用直到運行時才定義的類型的方法等)並不是最強大的。

Invokation是這樣的:

InvokationHelper<MyObjectType, MyObjectType> helper = new InvokationHelper<MyObjectType, MyObjectType>(); 

try 
{ 
    MyObjectType resultObject = helper.InvokeAction(container, myServiceObject, "MyActionName"); 
} 
catch (Exception e) 
{ 
    // Handle failure of the invokation 
} 

應當注意的是,爲了得到擴展類型,你需要裝飾用[FromODataUri]屬性您EntitySetControllers操作方法。這將對傳遞的關鍵參數執行適當的Edm類型。如果沒有這個,你會得到來自Edm的解析錯誤,用於在URI行中修飾的類型。例如,一個具有像.../EntitySet(12345L)/ ActionName這樣的URI的EntitySet將在解析中拋出錯誤。名義上,其目的是將參數解碼爲類型Edm.Int64的,但這種情況不會發生,而不[FromODataUri]屬性爲:

[HttpPost] 
public ReturnEntityType ActionName([FromODataUri]long key) 
{ 
    ... 
} 

這是一個非常令人沮喪的錯誤,我打獵,和我已經將它作爲一個bug提交給MS。原來它只是需要輸入參數的類型修飾。

2

您是否考慮過使用ASP.NET Web API OData?它支持OData操作,使用Web API實現它們非常簡單。你可以在這個博客post找到更多信息。