2013-04-03 30 views
3

我正在使用OData構建Web API服務,並且想按如下方式在服務中公開方法。ASP.NET Web API在EDM模型根目錄下的OData操作

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") 

但是,如果我不想將動作與實體相關聯,那麼我會在哪裏編寫動作的方法?是否有我需要寫的DefaultController類?

回答

7

我們目前不支持這個開箱即用,但它很容易做到這一點。下面的例子(這個很好的例子實際上來自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", "odata", 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); 
    } 
}  
+0

這正是我所期待的。我看到這個動作顯示在'http:// myServer/odata/$ metadata'中,但是我怎樣從客戶端調用它?我目前正在使用WCF數據服務5.1(OData3)驅動程序進行連接測試,並且希望將OData操作看作是一種方法。但是,在LINQPad中,不可綁定的動作和綁定到實體集合的動作都不可見。 – MCattle 2013-04-04 17:51:21

+0

我發現這個,應該指向正確的方向:http://msdn.microsoft.com/en-us/library/hh859851(v=vs.103).aspx#sectionToggle3 – MCattle 2013-04-04 19:50:26

+0

@KiranChalla有沒有關於這方面的最新新進展得到了開箱即用的支持? – mare 2013-11-26 12:09:00