我正在使用OData构建Web API服务,并希望在服务中将方法公开为Action,如下所示.
http://myServer/odata/myAction
我目前正在映射OData路由如下:
Dim modelBuilder As ODataModelBuilder = New ODataConventionModelBuilder modelBuilder.EntitySet(Of Product)("Products") Dim myAction = modelBuilder.Action("myAction") myAction.Parameter(Of String)("Parameter1") myAction.Returns(Of Boolean)() Dim model As IEdmModel = modelBuilder.GetEdmModel config.Routes.MapODaTaroute("ODaTaroute","odata",model)
This wonderful tutorial显示了如何将动作与这样的实体相关联:
http://myServer/odata/Products(1)/myAction
在本教程之后,我可以在使用以下行创建模型后,在ProductsController类中编写操作的方法:
Dim myAction = modelBuilder.Entity(Of Product).Action("myAction")
解决方法
我们目前没有开箱即用的支持,但它很容易自己做.下面的例子(这个漂亮的样本实际上来自Mike Wasson,尚未公开:-))
------------------------------------------------------ // CreateMovie is a non-bindable action. // You invoke it from the service root: ~/odata/CreateMovie ActionConfiguration createMovie = modelBuilder.Action("CreateMovie"); createMovie.Parameter<string>("Title"); createMovie.ReturnsFromEntitySet<Movie>("Movies"); // Add a custom route convention for non-bindable actions. // (Web API does not have a built-in routing convention for non-bindable actions.) IList<IODaTaroutingConvention> conventions = ODaTaroutingConventions.CreateDefault(); conventions.Insert(0,new NonBindableActionRoutingConvention("NonBindableActions")); // Map the OData route. Microsoft.Data.Edm.IEdmModel model = modelBuilder.GetEdmModel(); config.Routes.MapODaTaroute("ODaTaroute",model,new DefaultODataPathHandler(),conventions); -------------------------------------------------------------- // Implements a routing convention for non-bindable actions. // The convention maps "MyAction" to Controller:MyAction() method,where the name of the controller // is specified in the constructor. public class NonBindableActionRoutingConvention : IODaTaroutingConvention { private string _controllerName; public NonBindableActionRoutingConvention(string controllerName) { _controllerName = controllerName; } // Route all non-bindable actions to a single controller. public string SelectController(ODataPath odataPath,System.Net.Http.HttpRequestMessage request) { if (odataPath.PathTemplate == "~/action") { return _controllerName; } return null; } // Route the action to a method with the same name as the action. public string SelectAction(ODataPath odataPath,System.Web.Http.Controllers.HttpControllerContext controllerContext,ILookup<string,System.Web.Http.Controllers.HttpActionDescriptor> actionMap) { if (controllerContext.Request.Method == HttpMethod.Post) { if (odataPath.PathTemplate == "~/action") { ActionPathSegment actionSegment = odataPath.Segments.First() as ActionPathSegment; IEdmFunctionImport action = actionSegment.Action; if (!action.IsBindable && actionMap.Contains(action.Name)) { return action.Name; } } } return null; } } -------------------------------------------------- // Controller for handling non-bindable actions. [ODataFormatting] [ApiExplorerSettings(IgnoreApi = true)] public class NonBindableActionsController : ApiController { MoviesContext db = new MoviesContext(); [HttpPost] public Movie CreateMovie(ODataActionParameters parameters) { if (!ModelState.IsValid) { throw new HttpResponseException(HttpStatusCode.BadRequest); } string title = parameters["Title"] as string; Movie movie = new Movie() { Title = title }; db.Movies.Add(movie); db.SaveChanges(); return movie; } protected override void dispose(bool disposing) { db.dispose(); base.dispose(disposing); } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。