Xamarin Android表单提交API触发InternalServerError问题求助
Xamarin Forms调用API遇InternalServerError问题
在物理Android设备上运行Xamarin Forms应用提交表单时,提示Exception: InternalServerError,但Postman、电脑浏览器及手机浏览器调用该API均正常工作。
相关代码
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TEST.MainPage"> <StackLayout> <Entry x:Name="IdMarqueEntry" Placeholder="Enter Id Marque" /> <Entry x:Name="NomMarqueEntry" Placeholder="Enter Nom Marque" /> <Button Text="Submit" Clicked="OnSubmitClicked" /> <Label x:Name="ResultLabel" Text="Result will be displayed here" /> </StackLayout> </ContentPage>
MainPage.xaml.cs
using Newtonsoft.Json; using PFAG1_2Cars.Core.Entities; // 引用Marque类所在的命名空间 using System; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Xamarin.Forms; namespace TEST { public partial class MainPage : ContentPage { private readonly HttpClient _httpClient; public MainPage() { InitializeComponent(); _httpClient = new HttpClient(); _httpClient.BaseAddress = new Uri("http://192.168.x.x:5050/api/"); } private async void OnSubmitClicked(object sender, EventArgs e) { var marque = new Marque { IdMarque = int.Parse(IdMarqueEntry.Text), NomMarque = NomMarqueEntry.Text }; var json = JsonConvert.SerializeObject(marque); var content = new StringContent(json, Encoding.UTF8, "application/json"); try { var response = await _httpClient.PostAsync("your", content); if (response.IsSuccessStatusCode) { ResultLabel.Text = "Marque added successfully!"; } else { ResultLabel.Text = $"Error: {response.StatusCode}"; } } catch (Exception ex) { ResultLabel.Text = $"Exception: {ex.Message}"; } } } }
App.xaml.cs
using System; using Xamarin.Forms; using Microsoft.Extensions.DependencyInjection; using PFAG1_2Cars.Core.Services; using PFAG1_2Cars.Data; using PFAG1_2Cars.Services.Services; using PFAG1_2Cars.Core; using PFAG1_2Cars.Data.UnitOfWork; using PFAG1_2Cars.Data.Repositories; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System.IO; using PFAG1_2Cars.Core.Repositories; namespace TEST { public partial class App : Application { // 用于存储服务提供者的静态属性 public static IServiceProvider ServiceProvider { get; private set; } public App() { InitializeComponent(); // 配置依赖注入 ConfigureServices(); // 将MainPage设置为导航页面的根页 MainPage = new NavigationPage(new MainPage()); } private void ConfigureServices() { var services = new ServiceCollection(); var connectionString = "Server=192.168.x.x\\SQLEXPRESS,1433;Database=xxx;User Id=xxx;Password=xxx;"; // 使用直接传入的连接字符串注册数据层的DbContext services.AddDbContext<PFAG1_2CarsDbContext>(options => options.UseSqlServer(connectionString)); // 注册工作单元及其他所需服务 services.AddScoped<IUnitOfWork, UnitOfWork>(); services.AddScoped<IMarqueService, MarqueService>(); // 注册仓储类 services.AddScoped<IAssuranceRepository, AssuranceRepository>(); services.AddScoped<ICarRepository, CarRepository>(); services.AddScoped<ICategorieRepository, CategorieRepository>(); services.AddScoped<ICompanyAssuranceRepository, CompanyAssuranceRepository>(); services.AddScoped<ICompteRepository, CompteRepository>(); services.AddScoped<IControleTechniqueRepository, ControleTechniqueRepository>(); services.AddScoped<IInterventionRepository, InterventionRepository>(); services.AddScoped<IMarqueRepository, MarqueRepository>(); services.AddScoped<IModelRepository, ModelRepository>(); services.AddScoped<IPrestationRepository, PrestationRepository>(); services.AddScoped<IRoleRepository, RoleRepository>(); // 构建服务提供者 ServiceProvider = services.BuildServiceProvider(); } protected override void OnStart() { // 处理应用启动逻辑 } protected override void OnSleep() { // 处理应用休眠逻辑 } protected override void OnResume() { // 处理应用恢复逻辑 } } }
appsettings.json
{ "ConnectionStrings": { "DefaultConnection": "Server=192.168.x.x\\SQLEXPRESS,1433;Database=xxx;User Id=xxx;Password=xxx;Encrypt=False;" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "ApiBaseUrl": "https://192.168.x.x:5050/api/" }
YourController.cs
using Microsoft.AspNetCore.Mvc; using PFAG1_2Cars.Core; using PFAG1_2Cars.Core.Entities; using PFAG1_2Cars.Core.Repositories; using PFAG1_2Cars.Core.Services; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace Web.API.Controllers { [Route("api/[controller]")] [ApiController] public class YourController : ControllerBase { private readonly IMarqueService _marqueService; public YourController(IMarqueService marqueService) { _marqueService = marqueService; } // GET: api/marque [HttpGet] public async Task<ActionResult<IEnumerable<Marque>>> GetMarques() { try { var marques = await _marqueService.GetAllMarques(); return Ok(marques); } catch (Exception ex) { return StatusCode(500, $"Internal server error: {ex.Message}"); } } // GET: api/marque/5 [HttpGet("{id}")] public async Task<ActionResult<Marque>> GetMarque(int id) { try { var marque = await _marqueService.GetMarqueById(id); if (marque == null) { return NotFound(); } return Ok(marque); } catch (Exception ex) { return StatusCode(500, $"Internal server error: {ex.Message}"); } } // POST: api/marque [HttpPost] public async Task<ActionResult<Marque>> PostMarque(Marque marque) { try { var newMarque = await _marqueService.CreateMarque(marque); return CreatedAtAction(nameof(GetMarque), new { id = newMarque.IdMarque }, newMarque); } catch (Exception ex) { return StatusCode(500, $"Internal server error: {ex.Message}"); } } // PUT: api/marque/5 [HttpPut("{id}")] public async Task<IActionResult> PutMarque(int id, Marque marque) { try { await _marqueService.UpdateMarque(new Marque { IdMarque = id }, marque); return NoContent(); } catch (Exception ex) { return StatusCode(500, $"Internal server error: {ex.Message}"); } } // DELETE: api/marque/5 [HttpDelete("{id}")] public async Task<IActionResult> DeleteMarque(int id) { try { await _marqueService.DeleteMarqueById(id); return NoContent(); } catch (Exception ex) { return StatusCode(500, $"Internal server error: {ex.Message}"); } } } }
排查与解决思路
1. 修正API端点路径匹配
Xamarin代码中调用的是PostAsync("your", content),但控制器类名为YourController,实际API端点应为api/your,但控制器内POST方法注释标注的是api/marque,存在路径不匹配问题。建议将控制器类名改为MarqueController,同时将Xamarin中的请求路径改为api/marque,确保路由一致。
2. 配置Android网络权限与明文流量
- 在Android项目的
AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - 若API使用HTTP协议,在Android 9及以上版本需允许明文流量,在
<application>标签中添加:android:usesCleartextTraffic="true"
3. 捕获API详细错误信息
修改Xamarin中的异常处理代码,获取API返回的具体错误内容:
catch (Exception ex) { string errorDetail = string.Empty; if (response != null) { errorDetail = await response.Content.ReadAsStringAsync(); } ResultLabel.Text = $"Exception: {ex.Message}, 错误详情: {errorDetail}"; }
4. 验证设备与服务器网络连通性
确保物理Android设备与API服务器处于同一局域网,可在设备浏览器中访问http://192.168.x.x:5050/api/your(或对应正确路径),确认能正常返回数据。
5. 查看API服务器日志
检查ASP.NET Core服务器的日志输出,获取InternalServerError的具体异常栈信息,定位是否为数据库连接失败、服务层逻辑错误等问题。
内容的提问来源于stack exchange,提问作者Mohammed Elyaakoubi
相关产品推荐
相关产品推荐

