为什么在成功更新后此 HttpClient PutAsync returns 内部服务器错误
why does this HttpClient PutAsync returns internal server error after a successful update
我有一个 HttpPut API 方法可以编辑传递给它的对象并成功保存到数据库中。这工作正常,但是从我的 MVC 应用程序中,我用来调用我的 API Put 方法 returns 内部服务器错误的 httpClient.PutAsync,即使 API Put 方法没有.
我不确定出了什么问题,API 方法工作正常,但不知何故 MVC HttpClient 仍然出现内部服务器错误。
API 放置方法
[HttpPut]
public IActionResult Put([FromBody] School school)
{
try
{
var schoolExists = _schoolRepository.SchoolExists(school.Id);
if (!schoolExists) return NotFound();
if (!ModelState.IsValid) return BadRequest();
var schoolData = Mapper.Map<School, Data.School>(school);
var updatedClass = _schoolRepository.UpdateSchool(schoolData);
if (!updatedClass) return Json(GetHttpResponseMessage(HttpStatusCode.InternalServerError));
var route = CreatedAtRoute("GetSchool", school);
return route;
}
catch (Exception e)
{
return LogException(e);
}
}
上面的方法工作正常,我的更改被保存到数据库中,CreatedAtRouteResult 对象从 API 方法返回。
MVC HTTPCLIENT
public async Task<T> PutObject(string path, T content, string accessToken)
{
using (var httpClient = new HttpClient())
{
try
{
SetBaseUri(httpClient, accessToken);
var serialisezContent = CreateHttpContent(content);
var httpResponse = await httpClient.PutAsync(path, serialisezContent);
if (httpResponse.StatusCode == HttpStatusCode.InternalServerError) throw new Exception("Problem accessing the api");
return JsonConvert.DeserializeObject<T>(GetResult(httpResponse));
}
catch (Exception ex)
{
throw ex;
}
}
}
上面的方法是问题所在,这行var httpResponse = await httpClient.PutAsync(path, serialisezContent);
returns内部服务器错误仍然存在。我的 POST 有相同的实现,而且效果很好。
SETBASEURI()
private void SetBaseUri(HttpClient httpClient, string accessToken)
{
httpClient.BaseAddress = new Uri(BaseUri);
httpClient.DefaultRequestHeaders.Authorization =
_authenticationHeaderValueCreator.CreateAuthenticationHeaderValue("bearer", accessToken);
}
CreateHttpContent()
public ByteArrayContent CreateHttpContent<TParam>(TParam httpObject)
{
var content = JsonConvert.SerializeObject(httpObject);
var buffer = System.Text.Encoding.UTF8.GetBytes(content);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return byteContent;
}
我打赌你的 API Put 方法确实 returns HTTP 500 错误消息 No route matches the supplied values
。您可以在 Fiddler 中查看它。
问题出在以下行:
var route = CreatedAtRoute("GetSchool", school);
CreatedAtRoute
方法将路由名称作为第一个参数。我怀疑您是否有一条名为 GetSchool
的路线。它更像是同一个控制器中的一个动作名称。 CreatedAtRoute
不会为未知路由抛出异常,它只会 return 500 错误代码。
要解决此问题,请使用 CreatedAtAction
方法而不是 CreatedAtRoute
:
var route = CreatedAtAction("GetSchool", school);
我认为问题在于 API 的结果无法序列化。尝试在单元测试中自己手动序列化结果,看看失败的地方。
我有一个 HttpPut API 方法可以编辑传递给它的对象并成功保存到数据库中。这工作正常,但是从我的 MVC 应用程序中,我用来调用我的 API Put 方法 returns 内部服务器错误的 httpClient.PutAsync,即使 API Put 方法没有.
我不确定出了什么问题,API 方法工作正常,但不知何故 MVC HttpClient 仍然出现内部服务器错误。
API 放置方法
[HttpPut]
public IActionResult Put([FromBody] School school)
{
try
{
var schoolExists = _schoolRepository.SchoolExists(school.Id);
if (!schoolExists) return NotFound();
if (!ModelState.IsValid) return BadRequest();
var schoolData = Mapper.Map<School, Data.School>(school);
var updatedClass = _schoolRepository.UpdateSchool(schoolData);
if (!updatedClass) return Json(GetHttpResponseMessage(HttpStatusCode.InternalServerError));
var route = CreatedAtRoute("GetSchool", school);
return route;
}
catch (Exception e)
{
return LogException(e);
}
}
上面的方法工作正常,我的更改被保存到数据库中,CreatedAtRouteResult 对象从 API 方法返回。
MVC HTTPCLIENT
public async Task<T> PutObject(string path, T content, string accessToken)
{
using (var httpClient = new HttpClient())
{
try
{
SetBaseUri(httpClient, accessToken);
var serialisezContent = CreateHttpContent(content);
var httpResponse = await httpClient.PutAsync(path, serialisezContent);
if (httpResponse.StatusCode == HttpStatusCode.InternalServerError) throw new Exception("Problem accessing the api");
return JsonConvert.DeserializeObject<T>(GetResult(httpResponse));
}
catch (Exception ex)
{
throw ex;
}
}
}
上面的方法是问题所在,这行var httpResponse = await httpClient.PutAsync(path, serialisezContent);
returns内部服务器错误仍然存在。我的 POST 有相同的实现,而且效果很好。
SETBASEURI()
private void SetBaseUri(HttpClient httpClient, string accessToken)
{
httpClient.BaseAddress = new Uri(BaseUri);
httpClient.DefaultRequestHeaders.Authorization =
_authenticationHeaderValueCreator.CreateAuthenticationHeaderValue("bearer", accessToken);
}
CreateHttpContent()
public ByteArrayContent CreateHttpContent<TParam>(TParam httpObject)
{
var content = JsonConvert.SerializeObject(httpObject);
var buffer = System.Text.Encoding.UTF8.GetBytes(content);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return byteContent;
}
我打赌你的 API Put 方法确实 returns HTTP 500 错误消息 No route matches the supplied values
。您可以在 Fiddler 中查看它。
问题出在以下行:
var route = CreatedAtRoute("GetSchool", school);
CreatedAtRoute
方法将路由名称作为第一个参数。我怀疑您是否有一条名为 GetSchool
的路线。它更像是同一个控制器中的一个动作名称。 CreatedAtRoute
不会为未知路由抛出异常,它只会 return 500 错误代码。
要解决此问题,请使用 CreatedAtAction
方法而不是 CreatedAtRoute
:
var route = CreatedAtAction("GetSchool", school);
我认为问题在于 API 的结果无法序列化。尝试在单元测试中自己手动序列化结果,看看失败的地方。