«Указанный запрос OData имеет недопустимый реальный литерал» - PullRequest
0 голосов
/ 04 июля 2018

Я разрабатываю приложение, используя бэкэнд мобильных приложений Xamarin.Android и Azure. Недавно я заметил, что на некоторых устройствах функция вызывает необработанное исключение.

Эта функция вызывает ошибку. Я запрашиваю маркеры карты из локальной базы данных на основе местоположения устройства, которое задается в качестве параметра.

public static async Task<List<Marker>> GetMarkersAroundPosition(LatLng position)
{
    if (position == null)
        throw new NullPointerException(Resources.System.GetString(Resource.String.dbErrorPositionNullOrEmpty));

    //Calculate the latitude at the current longitude
    double lonInKm = CalcLat(position.Longitude);
    //Fetch the markers from DB
    return await Client.GetSyncTable<Marker>().Where(Marker => Marker.Lat < position.Latitude + Constants.LatInKm
    && Marker.Lat > position.Latitude - Constants.LatInKm
    && Marker.Lon < position.Longitude + lonInKm 
    && Marker.Lon > position.Longitude - lonInKm).ToListAsync();
}

Это ошибка, которую я получаю:

Microsoft.WindowsAzure.MobileServices.MobileServiceODataException: The specified odata query has invalid real literal '60.9852519308129'.

Я загрузил полную трассировку стека здесь .

Это происходит только на определенных устройствах. Вот список физических устройств, на которых я тестировал приложение:

Works:
    Lenovo Tab 4 8 LTE (TB-8504X), 7.1.1
    Alcatel Idol 4 (TLC 6055K) 6.0.1
    Motorola Moto G5S Plus (XT1805), 7.1.1
    Motorola Moto G5 (XT1676), 7.0
    Samsung Samsung Galaxy Tab A 9.7 (SM-T550), 7.1.1
    Samsung Galaxy Tab 3 10.1 (GT-P5220), 7.1.2 (LineageOS 14.1)
    Sony Xperia XZ1 (G8441), 8.0.0

Doesn't:
    Motorola Moto X Play (XT1652), 7.1.1
    Nokia 6 TA1021, 8.1.0
    Samsung Galaxy Note8 (SM-N950F), 8.0.0
    Motorola Moto G5 Plus (XT1685), 7.0
    OnePlus 3T (A3003) 8.0.0

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

EDIT:

Кажется, это проблема локали. Я создал небольшое тестовое приложение для тестирования функции Double.TryParse, как предлагалось на форумах Xamarin , а также протестировал приложение в разработке на разных языках. Все тесты привели к сбою приложения, если бы язык устройства был установлен на финском, и работали совершенно нормально, когда язык был установлен на английский.

1 Ответ

0 голосов
/ 05 июля 2018

Microsoft.WindowsAzure.MobileServices.MobileServiceODataException: указанный запрос оддаты имеет недопустимый действительный литерал '60 .9852519308129 '.

Основываясь на вашей трассировке стека, я нашел строку кода, в которую сгенерировано исключение. Вы можете проверить метод ParseRealLiteral в ODataExpressionParser.cs следующим образом:

        private QueryNode ParseRealLiteral()
        {
            this.ValidateToken(QueryTokenKind.RealLiteral, () => "Expected real literal.");
            string text = this.lexer.Token.Text;
            char last = Char.ToUpper(text[text.Length - 1]);
            if (last == 'F' || last == 'M' || last == 'D')
            {
                // so terminating F/f, M/m, D/d have no effect.
                text = text.Substring(0, text.Length - 1);
            }
            object value = null;
            switch (last)
            {
                case 'M':
                    decimal mVal;
                    if (Decimal.TryParse(text, out mVal))
                    {
                        value = mVal;
                    }
                    break;
                case 'F':
                    float fVal;
                    if (Single.TryParse(text, out fVal))
                    {
                        value = fVal;
                    }
                    break;
                case 'D':
                default:
                    double dVal;
                    if (Double.TryParse(text, out dVal))
                    {
                        value = dVal;
                    }
                    break;
            }
            if (value == null)
            {
                this.ParseError("The specified odata query has invalid real literal '{0}'.".FormatInvariant(text), this.lexer.Token.Position);
            }

            this.lexer.NextToken();
            return new ConstantNode(value);
        }

Насколько я понимаю, ваш ввод 60.9852519308129(m|f|d) должен работать как положено, исходя из вашего конкретного подробного сообщения об ошибке.

07-04 11: 01: 05.653 I / MonoDroid (29937): в Microsoft.WindowsAzure.MobileServices.Query. MobileServiceTableQuery `1 + ToListAsync d__33 [T] .MoveNext (): 0 Произошло необработанное исключение.

Кажется, предложение where вызывает исключение. Я предполагаю, что это вызвано конкретными сохраненными данными или оператором запроса, пожалуйста, попробуйте использовать одну и ту же локальную базу данных SQLite, чтобы проверить эту проблему для каждого устройства. Кроме того, вы можете попробовать Отладка автономного кэша , чтобы определить, может ли это помочь вам диагностировать эту проблему.

...