我想你是对的。其基本思路看起来像:
/// <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。原来它只是需要输入参数的类型修饰。