我读过WCF Data Service 5.0 release notes,其中提到了OData Actions(不是服务方法)的实现。
在分析了tutorials后,我得出的结论是我需要为自己建立WCF Data Services Action Provider for Entity Framework。
该项目只有一个签到,此后一直没有更新。我认为它没有错误,但根据统计数据,我不希望有太多的客户群来分享经验。
您是否知道在.NET中实现OData操作的其他选项?
答案 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。原来它只需要输入参数上的类型装饰。