如何在OData v6.0.0中启用EnableCaseInsensitive,EnableEnumPrefixFree和EnableUnqualifiedNameCall

时间:2016-12-06 14:01:00

标签: odata url-routing

我最近将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.

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

1 个答案:

答案 0 :(得分:7)

我遇到了同样的问题。 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上发布了这个问题,但是现在没有团队的回答,这个工作范围是另一种选择,直到我们得到标准的东西。

Github link

此致 米哈伊