2015-10-05 5 views
1

У меня есть проект OData (v3) Web API 2, который является оболочкой для другого веб-сервиса wcf. Предполагаемый клиент для этого соединения odata - это SharePoint 2013. Я создаю операции CRUD в этой оболочке и заметил, что когда sharepoint предлагается удалить что-то, он отправляет запрос в таком формате:/Entity (Identity = XX), а не обычный/Entity (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 
      ); 
Смежные вопросы