Xamarin应用模拟器正常运行,真机抛出System.FormatException求助
Hey, this is a super common gotcha with cross-device testing! The issue almost certainly boils down to regional/culture setting differences between your Nexus 5X emulator and physical Android device. Let me break this down and show you how to fix it.
Why This Happens
When you call decimal.Parse(stringRate) without specifying a culture, it uses the device's default system culture. Emulators often default to US English (where decimal points are represented with .), but your physical device might be set to a locale that uses a different decimal separator (like , in many European countries) or different number formatting rules.
Even if the stringRate value looks identical to you, the parser interprets it differently based on the device's culture. For example:
- If your API returns
"45.67"(US-style decimal) - Your physical device uses a culture that expects
"45,67"(comma as decimal separator) decimal.Parsewill throw aFormatExceptionbecause it can't interpret the.correctly.
How to Fix It
The simplest and most reliable fix is to use invariant culture for parsing, which ignores the device's regional settings and uses a universal format (US-style by default). Here's how to modify your code:
using System.Globalization; // Don't forget to add this using directive public static async Task<decimal> ConvertCurrency(string curr, decimal amount) { var currency = await GetCurrency(curr); var stringRate = currency.Rate; // Use InvariantCulture to ensure consistent parsing across all devices var rate = decimal.Parse(stringRate, CultureInfo.InvariantCulture); var result = rate * amount; return result; }
Bonus: Add Error Handling (Recommended)
To make your code more robust, use decimal.TryParse instead of Parse—this avoids crashes entirely and lets you handle invalid rate values gracefully:
public static async Task<decimal?> ConvertCurrency(string curr, decimal amount) { var currency = await GetCurrency(curr); var stringRate = currency.Rate; if (decimal.TryParse(stringRate, NumberStyles.Any, CultureInfo.InvariantCulture, out var rate)) { var result = rate * amount; return result; } else { // Handle invalid rate format here (log error, return null, throw a custom exception, etc.) Console.WriteLine($"Failed to parse rate: '{stringRate}'"); return null; } }
Quick Debugging Tip
If you want to confirm the culture mismatch, add a log line to check the device's current culture and the raw stringRate value on your physical device:
Console.WriteLine($"Device culture: {CultureInfo.CurrentCulture.Name}"); Console.WriteLine($"Raw rate string: '{stringRate}'");
This will help you verify if the culture is indeed the culprit, or if there's a hidden issue (like unexpected whitespace or special characters in the rate string).
内容的提问来源于stack exchange,提问作者Patrik Jansson

