You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI中如何处理API返回的ProblemDetails响应

解决RequestProvider.PutAsync方法的错误返回问题

背景

我基于微软的.NET MAUI参考应用开发项目,其中的RequestProvider服务提供了与API交互的PutAsync方法,但该方法仅能返回泛型TResult类型。当API返回验证或其他错误时,会返回ProblemDetails格式的响应,我已经定义了ProblemDetailsWithErrors类来接收这类错误信息,现在需要修改PutAsync方法,使其能在出错时返回错误信息,成功时返回目标对象。

现有PutAsync方法代码

public async Task<TResult> PutAsync<TResult>(string uri, TResult data, string token = "", string header = "")
{
    HttpClient httpClient = GetOrCreateHttpClient(token);

    if (!string.IsNullOrEmpty(header))
    {
        RequestProvider.AddHeaderParameter(httpClient, header);
    }

    var content = new StringContent(JsonSerializer.Serialize(data));
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    HttpResponseMessage response = await httpClient.PutAsync(uri, content).ConfigureAwait(false);

    await RequestProvider.HandleResponse(response).ConfigureAwait(false);
    TResult result = await response.Content.ReadFromJsonAsync<TResult>();

    return result;
}

修改方案一:返回包含结果和错误的包装类

1. 定义通用响应包装类

创建泛型类同时承载成功结果与错误信息:

public class ApiResponse<TResult>
{
    public TResult SuccessResult { get; set; }
    public ProblemDetailsWithErrors ErrorResult { get; set; }
    public bool IsSuccess => ErrorResult == null;
}

2. 修改PutAsync方法

调整返回类型为ApiResponse<TResult>,根据响应结果序列化对应对象:

public async Task<ApiResponse<TResult>> PutAsync<TResult>(string uri, TResult data, string token = "", string header = "")
{
    HttpClient httpClient = GetOrCreateHttpClient(token);

    if (!string.IsNullOrEmpty(header))
    {
        RequestProvider.AddHeaderParameter(httpClient, header);
    }

    var content = new StringContent(JsonSerializer.Serialize(data));
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    HttpResponseMessage response = await httpClient.PutAsync(uri, content).ConfigureAwait(false);

    try
    {
        await RequestProvider.HandleResponse(response).ConfigureAwait(false);
        var successResult = await response.Content.ReadFromJsonAsync<TResult>();
        return new ApiResponse<TResult> { SuccessResult = successResult };
    }
    catch (Exception)
    {
        var errorResult = await response.Content.ReadFromJsonAsync<ProblemDetailsWithErrors>();
        return new ApiResponse<TResult> { ErrorResult = errorResult };
    }
}

3. 调用修改后的方法

通过IsSuccess区分场景,分别处理结果:

var apiResponse = await _requestProvider.PutAsync(uri, profile, authToken);
if (apiResponse.IsSuccess)
{
    var updatedProfile = apiResponse.SuccessResult;
    // 执行成功逻辑
}
else
{
    var errorDetails = apiResponse.ErrorResult;
    // 弹出错误提示,如显示errorDetails.Detail或errorDetails.Title
}

修改方案二:使用Try模式(返回布尔值+输出参数)

如果不想新增包装类,可采用Try模式:

public async Task<bool> TryPutAsync<TResult>(string uri, TResult data, out TResult successResult, out ProblemDetailsWithErrors errorResult, string token = "", string header = "")
{
    successResult = default;
    errorResult = default;
    HttpClient httpClient = GetOrCreateHttpClient(token);

    if (!string.IsNullOrEmpty(header))
    {
        RequestProvider.AddHeaderParameter(httpClient, header);
    }

    var content = new StringContent(JsonSerializer.Serialize(data));
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    HttpResponseMessage response = await httpClient.PutAsync(uri, content).ConfigureAwait(false);

    try
    {
        await RequestProvider.HandleResponse(response).ConfigureAwait(false);
        successResult = await response.Content.ReadFromJsonAsync<TResult>();
        return true;
    }
    catch (Exception)
    {
        errorResult = await response.Content.ReadFromJsonAsync<ProblemDetailsWithErrors>();
        return false;
    }
}

调用方式:

bool isSuccess = await _requestProvider.TryPutAsync(uri, profile, out var updatedProfile, out var errorDetails, authToken);
if (isSuccess)
{
    // 处理成功逻辑
}
else
{
    // 处理错误提示
}

注意事项

  • 原RequestProvider.HandleResponse方法通常会在响应状态码非2xx时抛出异常,因此通过捕获异常来序列化错误响应;如果该方法返回布尔值而非抛出异常,可直接用条件判断替代try-catch。
  • 确保ProblemDetailsWithErrors的属性名与API返回的ProblemDetails JSON字段完全匹配,避免序列化失败。

内容的提问来源于stack exchange,提问作者BryanCass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 21:45:11