【发布时间】:2021-10-04 12:47:10
【问题描述】:
我有一个视图,其中列出了与当前登录用户相关的预订。一旦用户单击其中一个预订,他就会导航到详细信息视图,该视图通过 httpclient 连接到 api 并获取预订详细信息。代码如下。
client.BaseAddress = new Uri(this.URL);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.TokenStr);
var result = await client.GetAsync($"/api/reservation/getforid?Id={id}");
client.Dispose();
if (result.StatusCode == System.Net.HttpStatusCode.OK)
{
var str = result.Content.ReadAsStringAsync().Result.Replace("\\", " ");
var model = JsonConvert.DeserializeObject<ReservationModel>(str);
return model;
}
详细信息页面还允许修改所选预订的某些数据,并在成功编辑后关闭视图并重新加载预订数据。
发生的情况是在 client.getAsync() 上引发 Java.Net.ProtocolException。并且在向 api 发出请求时,似乎 httpclient 并没有等待数据,而是得到了一些无法转换为响应对象的错误响应。
总结一下:
- 首次请求显示预订详情页面时,HttpClient 连接到 api 没有任何问题。
- 修改预订并尝试重新加载预订数据后,即使发出请求的代码/数据相同,也会引发异常
编辑:
我重构了我的项目,使其使用共享的 HttpClient 实例,并找到了导致问题的代码行。
private IMvxCommand submit;
public IMvxCommand Submit
{
get
{
submit = submit ?? new MvxAsyncCommand(async () =>
{
var validationResult = validateFields();
if (validationResult)
{
await _personApi.UpdatePerson(Model);
_nav.Close(this,true);
}
});
return submit;
}
}
_personApi.UpdatePerson() 方法似乎以某种方式搞砸了。 评论后视图关闭,列出人员的 ReservationDetailsView 成功获取数据。但是,当我取消注释该方法时,导航到 ReservationDetailViewModel 时会引发相同的异常...
您可以在下面看到 UpdatePerson 方法:
public async Task UpdatePerson(PersonModel model)
{
var token = GetCurrentToken();
//client = new HttpClient();
// client.BaseAddress = new Uri(this.URL);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.TokenStr);
// client.DefaultRequestHeaders.Add("content-type","application/json");
var dynamic = new { model.Id, model.Name, model.NumberPhone, model.Pesel, model.Street, model.Email, model.WhoToInfrom, model.PostalCode, model.CityPerson };
var content = new StringContent(JsonConvert.SerializeObject(dynamic), Encoding.UTF8, "application/json");
var result = await client.PostAsync($"/api/person/update", content);
}
编辑 2:
仍然卡在这个问题上,不管我使用 HttpClient 多少次,它都可以正常工作,直到我从 EditPersonViewModel 中的 PersonApi 调用 HttpClient 来更新人员。
任何后续调用实际上都会连接到我的 API(我设置了断点,没有抛出异常),但客户端收到如下响应。它来自哪里?
这是 IIS 记录的错误:
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 30.07.2021 11:14:01
Event time (UTC): 30.07.2021 09:14:01
Event ID: 17452691323540639122452734bf1713
Event sequence: 19
Event occurrence: 15
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/62/ROOT-4-132720999030559530
Trust level: Full
Application Virtual Path: /
Application Path: D:\www\abc\AbcHoliday\AbcHoliday\
Machine name: SERVER3
Process information:
Process ID: 11392
Process name: w3wp.exe
Account name: IIS APPPOOL\abc.syntio.pl
Exception information:
Exception type: TaskCanceledException
Exception message: A task was canceled.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.HttpServer.<SendAsync>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Owin.HttpMessageHandlerAdapter.<InvokeCore>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage.<RunApp>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.<DoFinalWork>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar)
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar)
at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Request information:
Request URL: http://abc.syntio.pl/api/reservation/getforid?Id=6384
Request path: /api/reservation/getforid
User host address: 10.10.0.1
User:
Is authenticated: True
Authentication Type: JWT
Thread account name: IIS APPPOOL\abc.syntio.pl
Thread information:
Thread ID: 25
Thread account name: IIS APPPOOL\abc.syntio.pl
Is impersonating: False
Stack trace: at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.HttpServer.<SendAsync>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Owin.HttpMessageHandlerAdapter.<InvokeCore>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage.<RunApp>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.<DoFinalWork>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar)
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar)
at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
【问题讨论】:
-
你检查过服务器日志,或者用 Postman 或浏览器测试过吗?存在许多关于“意外状态行”的问题,它们似乎指向服务器上的问题
-
您是否考虑过将 Submit 声明为
IMvxAsyncCommand而不是IMvxCommand?我不认为这是问题的一部分,但这是一种更好的做法,尤其是因为您已经在 lambda 中使用了 async/await。
标签: c# xamarin.forms mvvmcross