буквенно-цифровая строка в строковом параметре функции OData v4 анализируется как int в строку или null

У меня возникли проблемы с передачей буквенно-цифровой строки в качестве параметра для функции OData. Вот его подпись:

[EnableQuery]
    public IHttpActionResult GetForConstant([FromODataUri]string constant)

и его конфигурация:

var getForConstant = collection.Function("GetForConstant")
    .ReturnsFromEntitySet<BasicParameter>("Parameters");
getForConstant.Parameter<string>("constant");

и его метаданные:

<Function Name="GetForConstant" IsBound="true">
    <Parameter Name="bindingParameter" Type="Collection(MyApp.BasicParameter)" />
    <Parameter Name="constant" Type="Edm.String" Unicode="false" />
    <ReturnType Type="MyApp.BasicParameter" />
</Function>

Вот различные проанализированные значения параметра метода контроллера «константа» с соответствующим вызовом:

http://xxx/api/Parameters/Default.GetForConstant(constant='123')
constant: "123"

http://xxx/api/Parameters/Default.GetForConstant(constant='999999999999999999999999999999999999999999999999')
constant: "1E+48"

http://xxx/api/Parameters/Default.GetForConstant(constant='12aa') 
constant: "12" 

http://xxx/api/Parameters/Default.GetForConstant(constant='aa')
constant: null 

http://xxx/api/Parameters/Default.GetForConstant(constant='aa12') 
constant: null

Если я попробую без одинарных кавычек, я получу ошибку 406 Not Acceptable.

Я попытался обновить WebAPI 2.2 для OData до последней версии (5.4.0), а также обновить до последней версии ODataLib (6.10.0), но это не помогло.

Есть идеи, что случилось?

Если это имеет значение, я смешиваю WebAPI и MVC (для справочных страниц). Вот мои настройки маршрутизации.

МВК:

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute( //MapRoute for controllers inheriting from standard Controller
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

Веб-API:

public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute( //MapHTTPRoute for controllers inheriting ApiController
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
        );
    }

OData:

public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

        var builder = new ODataConventionModelBuilder() { Namespace = "Default" };

*snip! model configurations here*

        var model = builder.GetEdmModel();
        config.MapODataServiceRoute("ODataRoute", "api", model);
    }

person Jerther    schedule 06.02.2015    source источник
comment
Не могли бы вы показать нам метаданные $ для функции?   -  person Brad    schedule 07.02.2015
comment
@Brad, я добавил метаданные к вопросу.   -  person Jerther    schedule 09.02.2015
comment
Судя по тому, что вы показали, все выглядит нормально, хотя, очевидно, по какой-то причине ваша строка анализируется как число, прежде чем она будет предоставлена ​​​​вашему методу. Используете ли вы какие-либо пользовательские соглашения о маршрутизации, привязки моделей или что-то в этом роде?   -  person Brad    schedule 09.02.2015
comment
Помимо некоторого смешения MVC и WebAPI, все настолько просто, насколько это возможно. Я добавил конфигурации маршрутизации к вопросу.   -  person Jerther    schedule 09.02.2015
comment
Хм, совпадение между WebApi и OData интересно — я предполагаю, что сначала регистрируется OData? Тот факт, что ваша функция вызывается, кажется, предполагает, что это нормально. Что-то, что вы могли бы использовать в качестве отладки, это добавить атрибут ODataRoute к вашей функции [ODataRoute(/Parameters/Default.GetForConstants(constant={constant})] и посмотреть, поможет ли это. Если это так, это определенно предлагает маршрутизацию проблема.   -  person Brad    schedule 10.02.2015
comment
Я обязательно попробую это в ближайшее время. Между тем, вот сообщение в блоге, которое я сделал о смешивании mvc и webapi. Здесь могут содержаться некоторые полезные сведения, которые, как мне кажется, не связаны с моей проблемой: jerther.blogspot.ca/2014/11/   -  person Jerther    schedule 10.02.2015
comment
Добавление атрибута работает. Итак, вы говорите, что это будет означать проблему с маршрутизацией. Есть идеи, где посмотреть? Или мне действительно нужно установить этот атрибут для всех моих функций?   -  person Jerther    schedule 10.02.2015
comment
С этого момента становится немного неловко. Используемая вами перегрузка MapODataServiceRoute внутренне вызывает ODataRoutingConventions.CreateDefaultWithAttributeRouting, что внутренне добавляет ряд соглашений. Для этого следует использовать FunctionRoutingConvention, но его реализация должна работать со строками. Возможно, вы можете попробовать и посмотреть, какое соглашение на самом деле использовалось, но для этого, вероятно, потребуется отладка с использованием исходного кода из github (github. com/OData/WebApi)   -  person Brad    schedule 10.02.2015
comment
Выход. В этом случае мне лучше пока просто добавить атрибут. У меня не так много функций со строковыми параметрами, поэтому я могу с этим справиться. Вы можете превратить это в решение, и я приму его.   -  person Jerther    schedule 10.02.2015


Ответы (1)


Согласно цепочке комментариев к вопросу, похоже, что способ, которым соглашения о маршрутизации заполняют параметры функции, делает что-то странное. Поскольку маршрутизация на основе атрибутов является первой, которая запускается, ее использование, кажется, гарантирует, что произойдет «правильно».

Чтобы еще больше сузить проблему, потребуется отладка соглашений о маршрутизации, чтобы найти, какой из них выполняется для этого сценария, и что он делает для заполнения данных маршрута.

Между тем, добавление следующего атрибута в функцию работает:

[ODataRoute("/Parameters/Default.GetForConstant(constant={constant})"]
person Brad    schedule 10.02.2015
comment
У меня нет ODataRouteAttribute, поэтому это не работает. Есть предположения? - person JonathanPeel; 24.10.2016
comment
По-видимому, проблема 223 была решена с помощью сборки 5.5, какая сборка OData WebApi вы используете? - person Brad; 25.10.2016