2013-01-04 164 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找到更多信息。