调试器在解析 Rest API 响应 HttpClient、Xamarin Forms 时停止

Posted

技术标签:

【中文标题】调试器在解析 Rest API 响应 HttpClient、Xamarin Forms 时停止【英文标题】:Debugger Stops while Parsing Rest API response HttpClient, Xamarin Forms 【发布时间】:2019-06-22 06:45:12 【问题描述】:

我正在尝试解析来自 ASP.NET Core Web API 的响应。我能够成功地将响应 JSON 解析为 C# 对象,但是当解析的 C# 对象返回到 ViewModel 时,应用程序崩溃而不会引发任何错误。

在视图模型中

ApiResponse response = await _apiManager.GetAsync<ApiResponse>("authentication/GetUserById/1");

响应 JSON:


"result": 
    "id": 1,
    "userType": 1,
    "firstName": “FirstName”,
    "middleName": null,
    "lastName": “LastName”,        
,
"httpStatusCode": 200,
"httpStatusDescription": "200OkResponse",
"success": true,
"message": "hello"

HttpClient GetAsync() 方法:

 public async Task<TResult> GetAsync<TResult>(string endpoint)
    
        HttpResponseMessage httpResponse = _httpClient.GetAsync(endpoint).GetAwaiter().GetResult();
        httpResponse.EnsureSuccessStatusCode();
        TResult t = default(TResult);
        if (httpResponse.IsSuccessStatusCode)
        
            string serialized = await httpResponse.Content.ReadAsStringAsync();

            t =  JsonConvert.DeserializeObject<TResult>(serialized);
        
        return t;
    

应用程序在“return t”语句处崩溃(调试器停止而没有任何错误)。在这里,_httpClient 是使用 DI 的 HttpClient 的单例对象。

TResult 模型是 ApiResponse 对象

public class User

    [JsonProperty("id")]
    public int UserId  get; set; 
    [JsonProperty("userType")]
    public int UserType  get; set; 
    [JsonProperty("firstName")]
    public string FirstName  get; set; 
    [JsonProperty("middleName")]
    public string MiddleName  get; set; 
    [JsonProperty("lastName")]
    public string LastName  get; set;         


public abstract class ResponseBase

    [JsonProperty("httpStatusCode")]
    public int HttpStatusCode  get; protected set; 
    [JsonProperty("httpStatusDescription")]
    public string HttpStatusDescription  get; protected set; 
    [JsonProperty("success")]
    public bool Success  get; protected set; 
    [JsonProperty("message")]
    public string Message  get; protected set; 


public class ApiResponse : ResponseBase

    [JsonProperty("result")]
    public User Result  get; set;  = new User();

有两个问题: 1. 当下面的语句执行时,应用程序崩溃并且调试器停止并且不抛出任何错误。

HttpResponseMessage httpResponse = await _httpClient.GetAsync(endpoint).ConfigureAwait(false);

但是当用.GetAwaiter().GetResult()调用GetAsync()时,网络调用就成功了。我不明白为什么 ConfigureAwait(false) 失败。

HttpResponseMessage httpResponse = _httpClient.GetAsync(endpoint).GetAwaiter().GetResult();

    为什么以下调用失败并且应用程序崩溃?如何将解析后的 C# 对象返回给调用代码?

    return JsonConvert.DeserializeObject(序列化);

请指教。

【问题讨论】:

当我尝试在 ASP.NET Core MVC 中运行相同的代码时,它可以工作。它不会停止调试器。 GetAsync() 方法将响应返回给调用代码,没有任何错误。仅当我使用 Xamarin Forms 在 ios 模拟器上运行相同代码时才会中断代码 如果把return t;改成return new ApiResponse....,会不会又停了? 很抱歉,因为我忙于其他一些项目,所以延迟回复。当我将断点放在 ConfigureAwait(false) 语句下方的语句上时,我发现了一件有趣的事情,一切正常。但是当断点放在包含 ConfigureAwait(false) 方法的语句上时应用程序崩溃。 【参考方案1】:

试试这个

try

    var result = await httpClient.GetAsync(endpoint);
    var response = await result.Content.ReadAsStringAsync();
    data = JsonConvert.DeserializeObject<TResult>(response);
 
catch (Exception exp)

   Console.Write(exp.InnerMessage);

确保您已安装 Newtonsoft.Json

【讨论】:

解析代码没有问题。代码只有在 return t 执行时才会中断。 然后尝试使用ApiResponse模型解析 你的意思是说代替 TResult,我应该使用 ApiResponse 类。调用HttpClient的GetAsync()方法的代码是ApiResponse response = await _apiManager.GetAsync("authentication/GetUserById/1");

以上是关于调试器在解析 Rest API 响应 HttpClient、Xamarin Forms 时停止的主要内容,如果未能解决你的问题,请参考以下文章

Rest Template 无法正确解析 json rest api 响应

ReactJS:Rest API JSON 响应:如何解析

如何转换 REST API 响应

Android REST API 调用,后端没有响应新记录

概括 REST API 的分页技术

Laravel REST API 和高 CPU 负载