2016-12-06 2 views
3

최근 OData를 (v5.9.1)에서 최신 안정 버전 (v6.0.0)으로 업데이트했으며 이전 버전에서는 O : Data를 다음과 같이 구성했습니다.OData v6.0.0에서 EnableCaseInsensitive, EnableEnumPrefixFree 및 EnableUnqualifiedNameCall을 사용하는 방법

 //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

이것은 거의 완벽합니다. EnableCaseInsensitive 플래그가 false로 재설정되는 현재 OData 런타임의 '문제'가 있습니다. 항상 true를 반환하도록 EnableCaseInsensitive 속성을 변경하고 해결 방법으로 항상 랩핑 된 URI 분석기 EnableCaseInsensitive를 true로 설정해야 할 수도 있습니다. - 나는 이것에 대한 원인과 더 나은 해결책을 연구 중이고 모두에게 돌아갈 것이다. –

+0

고마워. 최근에 OData 팀과 꽤 잘 어울리지 않았습니다. 지난 몇 버전은 매우 버그가 많았고 문서는 업데이트되지 않았으며 버그 보고서는 무시되었습니다. 인상 지우지 않았다. – Porco