如何在 ASP.NET MVC Web 应用程序中使用 HttpContent 处理并发(状态 409)错误?
How to handle concurrency (status 409) errors using HttpContent in ASP.NET MVC Web application?
我正在开发 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
方法不完整,因为我试图找出如何处理 409 错误,如果 rowversion 值已过时,我从 API return。调用 response.EnsureSuccessStatusCode();
时,如果不是成功代码,则会抛出异常。我想我可以让它冒泡到前端并在控制器操作中处理它,但是异常对象不包含任何足以识别它是 409 错误的具体内容:
因此,如果这冒泡到控制器操作,我最好尝试从 message
中解析出状态代码,这似乎是个坏主意。
我可以从他们的 Web API 中找到人们 returning 409 代码的例子,但是当逻辑被分成不同的 类 而不是一次行动。
我该如何处理?我是否创建一个自定义异常并抛出它?也许使用 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中捕捉到,记录错误后处理。
我正在开发 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
方法不完整,因为我试图找出如何处理 409 错误,如果 rowversion 值已过时,我从 API return。调用 response.EnsureSuccessStatusCode();
时,如果不是成功代码,则会抛出异常。我想我可以让它冒泡到前端并在控制器操作中处理它,但是异常对象不包含任何足以识别它是 409 错误的具体内容:
因此,如果这冒泡到控制器操作,我最好尝试从 message
中解析出状态代码,这似乎是个坏主意。
我可以从他们的 Web API 中找到人们 returning 409 代码的例子,但是当逻辑被分成不同的 类 而不是一次行动。
我该如何处理?我是否创建一个自定义异常并抛出它?也许使用 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中捕捉到,记录错误后处理。