“指定的OData查询具有无效的真实文字”

时间:2018-07-04 10:02:34

标签: c# android xamarin.android odata azure-mobile-services

我正在使用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'.

我已经上传了完整的堆栈跟踪here

这仅在某些设备上发生。以下是我测试过该应用程序的物理设备的列表:

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

我真的迷失了它,因为似乎没有明确的理由说明该应用在某些设备上运行正常而在其他设备上崩溃。

编辑:

这似乎是语言环境问题。我创建了一个小型测试应用程序,用于测试Xamarin论坛上建议的Double.TryParse函数,并且还在开发中以不同的语言测试了该应用程序。所有测试结果都表明,如果设备语言设置为“芬兰语”,则该应用程序将崩溃,并且当该语言设置为英语时,该应用程序将完全正常运行。

1 个答案:

答案 0 :(得分:0)

  

Microsoft.WindowsAzure.MobileServices.MobileServiceODataException:指定的odata查询具有无效的真实文字'60 .9852519308129'。

根据您的堆栈跟踪,我找到了引发异常的代码行。您可以按以下方式检查ODataExpressionParser.cs下的ParseRealLiteral方法:

        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数据库来检查每个设备的此问题。此外,您可以尝试Debugging the Offline Cache来查找它是否可以帮助您诊断此问题。