我已经阅读了WCF Data Service 5.0的发布说明,其中提到了OData action(而不是服务方法)的实现。
在分析了教程之后,我得出的结论是,我需要为自己构建实体框架的WCF数据服务操作提供程序。
该项目只有一次签入,并且从那时起就没有更新过。我假设它没有漏洞,但根据统计数据,我不指望有太多的用户基础来分享体验。
你知道在。net中实现OData Actions的其他选项吗?
您考虑过使用ASP吗?. NET Web API OData?它支持OData操作,并且使用Web API实现这些操作非常简单。
我认为你是对的。其基本思路如下:
/// <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#语言边缘(比如创建泛型方法来调用直到运行时才定义的类型的方法等)并不是最强的。
调用类似于:
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类型。如果不这样做,对于URI行中修饰的类型,您将从Edm获得解析错误。例如,URI为…/EntitySet(12345L)/ActionName的EntitySet将在解析时抛出错误。名义上,目的是将参数解码为一种Edm类型。Int64,但如果没有[FromODataUri]属性,则不会发生这种情况:
[HttpPost]
public ReturnEntityType ActionName([FromODataUri]long key)
{
...
}
这对我来说是一个非常令人沮丧的bug,我已经把它作为一个bug提交给了微软。原来它只需要在输入参数上进行类型装饰。