2016-12-06 11 views
3

Недавно я обновил OData из (v5.9.1) до последней стабильной версии (v6.0.0), а в первой из них я сконфигурировал свою среду следующим образом:Как EnableCaseInsensitive, EnableEnumPrefixFree и EnableUnqualifiedNameCall в OData v6.0.0

 //Allows calling the Url like {entityAction}/{id} 
     config.SetUrlConventions(ODataUrlConventions.KeyAsSegment); 

     //Allows urls to be case insensitive 
     config.EnableCaseInsensitive(true); 

     // Remove the necessity of having to specify the namespace of enums. 
     config.EnableEnumPrefixFree(true); 

     //This allows call a function without using the full namespace. 
     config.EnableUnqualifiedNameCall(true); 

     config.MapODataServiceRoute("odata", "api/rest", 
     edmModel, new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer)); 

Теперь, после обновления, как я могу достичь того же результата, что и раньше? Ни один из моих маршрутов например: «локальный/OData/люди /» работают он показывает следующее сообщение:

The path template 'people/{parentId}/emails' on the action 'Get' in controller 'PersonEmails' is not a valid OData path template. The operation import overloads matching 'people' are invalid. This is most likely an error in the IEdmModel. 

Любые идеи? Заранее спасибо.

ответ

5

Я столкнулся с той же проблемой. Существует внутренний класс в System.Web.OData, называемый UnqualifiedCallAndEnumPrefixFreeResolver. Это теоретически будет обрабатывать как EnumPrefixFree, так и UnqualifiedNameCall, но поскольку это внутреннее я должен был написать свой собственный пока.

public class UnqualifiedCallAndEnumPrefixFreeResolver : ODataUriResolver 
{ 
    private readonly StringAsEnumResolver _stringAsEnum = new StringAsEnumResolver(); 
    private readonly UnqualifiedODataUriResolver _unqualified = new UnqualifiedODataUriResolver(); 

    private bool _enableCaseInsensitive; 

    public override bool EnableCaseInsensitive 
    { 
     get { return this._enableCaseInsensitive; } 
     set 
     { 
      this._enableCaseInsensitive = value; 
      _stringAsEnum.EnableCaseInsensitive = this._enableCaseInsensitive; 
      _unqualified.EnableCaseInsensitive = this._enableCaseInsensitive; 
     } 
    } 

    #region UnqualifiedODataUriResolver 

    public override IEnumerable<IEdmOperation> ResolveBoundOperations(IEdmModel model, string identifier, 
     IEdmType bindingType) 
    { 
     return _unqualified.ResolveBoundOperations(model, identifier, bindingType); 
    } 

    public override IEnumerable<IEdmOperation> ResolveUnboundOperations(IEdmModel model, string identifier) 
    { 
     return _unqualified.ResolveUnboundOperations(model, identifier); 
    } 

    #endregion 

    #region StringAsEnumResolver 

    public override void PromoteBinaryOperandTypes(BinaryOperatorKind binaryOperatorKind, 
     ref SingleValueNode leftNode, ref SingleValueNode rightNode, out IEdmTypeReference typeReference) 
    { 
     _stringAsEnum.PromoteBinaryOperandTypes(binaryOperatorKind, ref leftNode, ref rightNode, out typeReference); 
    } 

    public override IEnumerable<KeyValuePair<string, object>> ResolveKeys(IEdmEntityType type, 
     IDictionary<string, string> namedValues, Func<IEdmTypeReference, string, object> convertFunc) 
    { 
     return _stringAsEnum.ResolveKeys(type, namedValues, convertFunc); 
    } 

    public override IEnumerable<KeyValuePair<string, object>> ResolveKeys(IEdmEntityType type, 
     IList<string> positionalValues, Func<IEdmTypeReference, string, object> convertFunc) 
    { 
     return _stringAsEnum.ResolveKeys(type, positionalValues, convertFunc); 
    } 

    public override IDictionary<IEdmOperationParameter, SingleValueNode> ResolveOperationParameters(
     IEdmOperation operation, IDictionary<string, SingleValueNode> input) 
    { 
     return _stringAsEnum.ResolveOperationParameters(operation, input); 
    } 

    #endregion 
} 

Использование будет выглядеть следующим образом:

configuration.MapODataServiceRoute(
      "ODataRoute", 
      null, 
      builder => 
       builder.AddService(ServiceLifetime.Singleton, sp => BuildModel()) 
        .AddService<IEnumerable<IODataRoutingConvention>>(ServiceLifetime.Singleton, sp => 
          ODataRoutingConventions.CreateDefaultWithAttributeRouting("ODataRoute", configuration)) 
        .AddService<ODataUriResolver>(ServiceLifetime.Singleton, sp => new UnqualifiedCallAndEnumPrefixFreeResolver 
        { 
         EnableCaseInsensitive = true 
        }) 
     );   

Я также отправил это на GitHub как вопрос, но пока нет ответа от команды, это workarround альтернатива, пока мы не получим что-то в стандарт.

Github link

С уважением, Михай

+0

Большое спасибо за Ваш ответ! Я попробую! – Bruno

+1

Это почти идеально. Существует «Проблема» с текущим временем выполнения OData, где флаг EnableCaseInsensitive сбрасывается на false. Возможно, вам придется изменить свойство EnableCaseInsensitive, чтобы всегда возвращать true, и всегда устанавливайте обернутые идентификаторы uri EnableCaseInsensitive в true в качестве обходного пути. - Я изучаю причину и лучшее решение для этого и вернусь к вам всем :) –

+0

Спасибо. В последнее время довольно разочарованы командой OData - последние версии пары были очень ошибочными, документация никогда не обновлялась, а отчеты об ошибках игнорируются. Не впечатлен – Porco