How to EnableCaseInsensitive, EnableEnumPrefixFree and EnableUnqualifiedNameCall in OData v6.0.0

六眼飞鱼酱① 提交于 2019-12-21 05:20:06

问题


I recently updated OData from (v5.9.1) to the latest stable version (v6.0.0) and in the former one I used to configure my environment like this:

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

Now after the update, how can I achieve the same result as before? None of my routes e.g: 'localhost/odata/people/' are working it shows the following message:

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.

Any ideas? Thanks in advance.


回答1:


I encountered the same issue. There is an internal class in System.Web.OData called UnqualifiedCallAndEnumPrefixFreeResolver. This in theory would handle both EnumPrefixFree and UnqualifiedNameCall, but as this is internal i had to write my own for now.

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
}

The usage would be as follows:

 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
                    })
        );          

I also posted this on GitHub as an issue, but for now no answer from the team, this workarround is an alternative until we get something in standard.

Github link

Regards, Mihai



来源:https://stackoverflow.com/questions/40997153/how-to-enablecaseinsensitive-enableenumprefixfree-and-enableunqualifiednamecall

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!