今天试了一下,在MAUI上调用WEB API。经常一番努力,终于调用成功。不过这里面还是有很多的坑。
MAUI分了好几个平台,一般来说,最容易成功的是Windows平台。
坑1:HttpClient的方法
总体来说,其实是用HttpClient来调用。
但是HttpClient的方法使用上,也有坑。
最开始我使用的是下面的一些接口:
await _client.GetFromJsonAsync<TodoItem>($"Todo/{id}");
HttpResponseMessage response = await _client.PostAsJsonAsync("Todo", info);
HttpResponseMessage response = await _client.PutAsJsonAsync($"Todo/{info.Id}", info);
这些接口在Windows上执行没有问题的,但是跑Android虚拟机的时候,直接报错了。
应该是这些接口都是属于扩展接口,只支持Windows平台的。
所以最终的接口都换成了下面这种形式:
Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
HttpResponseMessage response = await _client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<List<TodoItem>>(content, _serializerOptions);
}
完整TodoService类代码:
using System.Diagnostics;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using TodoMaui.Models;
namespace TodoMaui.Services;
public class TodoService : ITodoService
{
private HttpClient _client;
private JsonSerializerOptions _serializerOptions;
private IHttpsClientHandlerService _httpsClientHandlerService;
public TodoService(IHttpsClientHandlerService service)
{
#if DEBUG
_httpsClientHandlerService = service;
HttpMessageHandler handler = _httpsClientHandlerService.GetPlatformMessageHandler();
if (handler != null)
_client = new HttpClient(handler);
else
_client = new HttpClient();
#else
_client = new HttpClient();
#endif
_serializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
_client.BaseAddress = new Uri("http://192.168.126.149:5000/");
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<TodoItem> GetTodoItem(long id)
{
try
{
Uri uri = new Uri(string.Format(Constants.RestUrl, id));
HttpResponseMessage response = await _client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<TodoItem>(content, _serializerOptions);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return null;
}
public async Task<List<TodoItem>> GetTodoItems()
{
try
{
Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
HttpResponseMessage response = await _client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<List<TodoItem>>(content, _serializerOptions);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return null;
}
public async Task<TodoItem> AddTodoItem(TodoItem item)
{
try
{
string json = JsonSerializer.Serialize<TodoItem>(item, _serializerOptions);
StringContent content = new StringContent(json, Encoding.UTF8, "application/json");
Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
HttpResponseMessage response = await _client.PostAsync(uri, content);
if (response.IsSuccessStatusCode)
{
json = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<TodoItem>(json, _serializerOptions);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return null;
}
public async Task UpdateTodoItem(TodoItem item)
{
try
{
string json = JsonSerializer.Serialize<TodoItem>(item, _serializerOptions);
StringContent content = new StringContent(json, Encoding.UTF8, "application/json");
Uri uri = new Uri(string.Format(Constants.RestUrl, item.Id));
HttpResponseMessage response = await _client.PutAsync(uri, content);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
public async Task DeleteTodoItem(long id)
{
try
{
Uri uri = new Uri(string.Format(Constants.RestUrl, id));
HttpResponseMessage response = await _client.DeleteAsync(uri);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
坑2:Android权限
因为用到了联网的功能,需要添加权限。我的AndroidManifest.xml文件内容:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-sdk />
</manifest>
好久没玩Android系统了,忘了这货还有权限的设置。关键提示太不明显了。
坑3:禁用Http协议
Android默认是禁用HTTP协议的,如果要启用,要设置一下。我懒得去设置,就直接把WEB API改成HTTPS协议了。
标签:string,await,Uri,笔记,client,开发,MAUI,new,response From: https://www.cnblogs.com/wzwyc/p/17914566.html