问题描述
我正在研究 Core 3.1 Web API 和使用它的 MVC 应用程序。在 MVC 应用程序中,我设置了包含 Update
方法的 UserRepo:
public async Task<User> Update(User user)
{
HttpClient client = _clientFactory.CreateClient("namedClient");
HttpResponseMessage response = await client.PutAsync($"api/Users/{user.Id}",ContentEncoder.Encode(user));
try
{
response.EnsureSuccessstatusCode();
}
catch (Exception ex)
{
if ((int)response.StatusCode == StatusCodes.Status409Conflict)
{
throw;
}
}
return await response.Content.ReadFromJsonAsync<User>();
}
repo 被注入到一个服务中,而该服务被注入到一个控制器中,这是我想要处理错误的地方。
Update
方法不完整,因为我试图弄清楚如果 rowversion 值已过时,我如何处理从 API 返回的 409 错误。调用 response.EnsureSuccessstatusCode();
时,如果不是成功代码,则会引发异常。我想我可以让它冒泡到前端并在控制器操作中处理它,但异常对象不包含任何足够具体的内容来识别它是 409 错误:
因此,如果这冒泡到控制器操作,我所能做的就是尝试从 message
中解析出状态代码,这似乎是个坏主意。
我可以找到人们从他们的 Web API 返回 409 代码的例子,但没有找到当逻辑被分成不同的类而不是全部在一个动作中时在 MVC 应用程序中如何处理这些代码的例子。
我该如何处理?我是否创建自定义异常并抛出该异常?也许使用 ex.Data.Add()
向异常添加其他数据并在操作中读取它?这是个坏主意吗?
解决方法
感谢@Peter Csala、@Craig H 和 @Filipe 的建议,这是我确定的解决方案。
调用API的方法:
public async Task<User> Update(User user)
{
HttpClient client = _clientFactory.CreateClient("namedClient");
HttpResponseMessage response = await client.PutAsync($"api/Users/{user.Id}",ContentEncoder.Encode(user));
await HttpResponseValidator.ValidateStatusCode(response);
return await response.Content.ReadFromJsonAsync<User>();
}
我可以重用的静态方法,它会在并发错误期间产生异常:
public static class HttpResponseValidator
{
public static async Task ValidateStatusCode(HttpResponseMessage response)
{
if ((int)response.StatusCode < 200 || (int)response.StatusCode > 299)
{
string errorResponse = await response.Content.ReadAsStringAsync();
if (response.StatusCode == HttpStatusCode.Conflict)
{
DBConcurrencyException ex = new DBConcurrencyException(errorResponse);
throw ex;
}
}
}
}
异常一直冒泡到调用 API 的方法的操作。我在 action 中捕获它并在记录错误后处理它。