实现WCF数据服务OData操作

时间:2013-01-04 16:28:30

标签: .net wcf wcf-data-services odata

我读过WCF Data Service 5.0 release notes,其中提到了OData Actions(不是服务方法)的实现。

在分析了tutorials后,我得出的结论是我需要为自己建立WCF Data Services Action Provider for Entity Framework

该项目只有一个签到,此后一直没有更新。我认为它没有错误,但根据统计数据,我不希望有太多的客户群来分享经验。

您是否知道在.NET中实现OData操作的其他选项?

2 个答案:

答案 0 :(得分:2)

您是否考虑过使用ASP.NET Web API OData?它支持OData操作,使用Web API实现它们很简单。您可以在此博客post找到更多信息。

答案 1 :(得分: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 Action方法。这将对传递的关键参数强制执行适当的Edm类型。如果没有这个,你将从Edm获得在URI行中修饰的类型的解析错误。例如,具有类似... / EntitySet(12345L)/ ActionName的URI的EntitySet将在解析中抛出错误。名义上,目的是将参数解码为Edm.Int64的类型,但如果没有[FromODataUri]属性,则不会发生这种情况:

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

对于我来说,这是一个非常令人沮丧的错误,我已将其作为一个错误提交给MS。原来它只需要输入参数上的类型装饰。