2015-10-05 68 views
1

我有一個OData(v3)Web API 2項目,它是另一個wcf Web服務的包裝。此odata連接的預期客戶端是SharePoint 2013.我在此包裝器中創建CRUD操作,並注意到在要求Sharepoint刪除某些內容時,會以此格式發送請求:/ Entity(Identity = XX),而不是正常/實體(XX)我工作正常。我需要能夠處理該請求而不會破壞另一個請求。這是我的代碼:具有可選參數的OData路由

public IHttpActionResult GetSchool([FromODataUri] int key, ODataQueryOptions<School> queryOptions) 
    { 
     // validate the query. 
     try 
     { 
      queryOptions.Validate(_validationSettings); 
     } 
     catch (ODataException ex) 
     { 
      return BadRequest(ex.Message); 
     } 
     SchoolDataSource data = new SchoolDataSource(); 
     var result = data.GetByID(key); 
     return Ok<School>(result); 
     //return StatusCode(HttpStatusCode.NotImplemented); 
    } 

這工作正常用於/學校的請求(1),但不用於/學校(ID = 1)。我曾嘗試添加: [Route("Schools(ID={key}")] 這使得/ Schools(ID = 1)路線工作,但打破幾乎所有其他事情(406錯誤)。我試圖添加上述屬性和 [Route("Schools({key})")],看看我是否可以讓他們都工作,但它也無法正常工作。我對此很新,希望至少能有一些方向。這裏是我的WebApiConfig:

 config.MapHttpAttributeRoutes(); 
     config.EnableQuerySupport(); 
     config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; 

     // Web API configuration and services 
     ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); 
     builder.EntitySet<School>("Schools"); 
     builder.DataServiceVersion = new Version("2.0"); 
     config.Routes.MapODataRoute("odata", null, builder.GetEdmModel()); 
     // Web API routes 


     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional } 
     ); 

錯誤,我得到: 406,如果我有路徑屬性設置。 500如果我沒有設置路由屬性。它似乎好像我的服務不知道如何處理參數,除非我指定它,但如果我這樣做,所有的調用會得到406錯誤。

回答

0

可能不是最好的方法,但使它與此類工作:

public class SharePointRoutingConvention : EntitySetRoutingConvention 
{ 
    public override string SelectAction(ODataPath odataPath, HttpControllerContext context, 
     ILookup<string, HttpActionDescriptor> actionMap) 
    { 
     //Gets the entity type 
     IEdmEntityType entityType = odataPath.EdmType as IEdmEntityType; 

     //makes sure the format is correct 
     if (odataPath.PathTemplate == "~/entityset/key") 
     { 
      //parses out the path segment (Identity=X) 
          KeyValuePathSegment segment = odataPath.Segments[1] as KeyValuePathSegment; 

      //Gets the verb from the request header 
      string actionName = context.Request.Method.ToString(); 

      // Add keys to route data, so they will bind to action parameters. 
      KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; 

      //Checks to see if the "Identity=" part is in the url 
      if (keyValueSegment.Value.Contains("Identity=")) 
      { 
       //removes the extra text 
       context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value.Replace("Identity=", ""); 
      } 
      else 
      { 
       //parses it normally 
       context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; 
      } 

      //returns the verb 
      return actionName; 

     } 
     // Not a match. 
     return null; 
    } 
} 

,並進行更改到webapiconfig:

 var conventions = ODataRoutingConventions.CreateDefault(); 

     //adding the custom odata routing convention 
     conventions.Insert(0, new SharePointRoutingConvention()); 



    config.Routes.MapODataRoute(
      routeName: "odata", 
      routePrefix: null,//this is so that you can type the base url and get metadata back (http://localhost/) 
      model: builder.GetEdmModel(), 
      pathHandler: new DefaultODataPathHandler(), 
      routingConventions: conventions //this assigns the conventions to the route 
      );