【问题标题】:How to EnableCaseInsensitive, EnableEnumPrefixFree and EnableUnqualifiedNameCall in OData v6.0.0如何在 OData v6.0.0 中启用CaseInsensitive、EnableEnumPrefixFree 和 EnableUnqualifiedNameCall
【发布时间】:2017-04-21 04:44:48
【问题描述】:

我最近将 OData 从 (v5.9.1) 更新到最新的稳定版本 (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));

现在更新后,我怎样才能达到和以前一样的效果?我的路线都没有,例如:'localhost/odata/people/' 正在运行它显示以下消息:

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.

有什么想法吗?提前致谢。

【问题讨论】:

    标签: odata url-routing


    【解决方案1】:

    我遇到了同样的问题。 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

    问候, 米海

    【讨论】:

    • 非常感谢您的回答!我试试看!
    • 这几乎是完美的。当前 OData 运行时存在“问题”,其中 EnableCaseInsensitive 标志重置为 false。您可能需要将 EnableCaseInsensitive 属性更改为始终返回 true,并始终将包装的 uri 解析器 EnableCaseInsensitive 设置为 true 作为解决方法。 - 我正在研究原因和更好的解决方案,并会回复大家:)
    • 谢谢。最近对 OData 团队非常失望——最近的几个版本有很多错误,文档永远不会更新,错误报告也被忽略了。没有留下深刻印象
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    • 2019-12-05
    相关资源
    最近更新 更多