从嵌套控制器返回 Ok() 时出现奇怪的问题
strange issue when returning Ok() from nested controller
我们有一个休息界面,一切正常,但一些客户希望能够通过门户上传 xml 文件。
我解析上传的文件,然后创建相应的控制器,如果数据通过 rest 接口以正确的格式发送,就会使用该控制器。
一切正常,除了一条错误消息从嵌套控制器 return 发送到我的 ajax,仅当我 return Ok();我觉得这很奇怪。一定是在管道中很晚才出现问题,因为我似乎根本无法捕捉到任何异常。
我在下面用一些示例控制器评论了一些代码来说明我的意思。
public class FileController : ApiController
{
[HttpPost]
public async Task<IHttpActionResult> UploadFile()
{
// if I return Ok(); from here it works fine.. so it's not the ajax
// Get the file details
var someParam = blah;
var someData = blah;
try
{
var restController = new RestController();
return await restController.SomeMethod(someParam, someData);
}
catch(Exception ex)
{
// No error is ever caught here
return new HttpExceptionResult(HttpStatusCode.InternalServerError, "Error uploading file");
}
}
}
public class RestController : ApiController
{
[HttpPost]
public async Task<IHttpActionResult> SomeMethod(someParam, someData)
{
// This returns fine
return new HttpExceptionResult(HttpStatusCode.409, "Something already exists");
// this fails -> returns okay, but my ajax receives a 500 internal server error
return Ok();
}
}
public class HttpExceptionResult : IHttpActionResult
{
private readonly HttpStatusCode _statusCode;
private readonly string _message;
public HttpExceptionResult(HttpStatusCode statusCode, string message)
{
_statusCode = statusCode;
_message = message;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage(_statusCode);
response.Content = new StringContent(_message);
return Task.FromResult(response);
}
}
我确定有一些事情我可以立即尝试修复它(使用我自己的 class 到 return 200 代码),但我想了解为什么这是内部发生的。有人有什么想法吗?
再次重新审视这个问题,看看我是否可以解决它,到目前为止我只设法找到了一种方法。
技巧似乎是将当前的 ControllerContext 传递给新的 Controller。
public class FileController : ApiController
{
[HttpPost]
public async Task<IHttpActionResult> UploadFile()
{
var someParam = blah;
var someData = blah;
try
{
var restController = new RestController()
{
ControllerContext = this.ControllerContext
};
// This now works
return await restController.SomeMethod(someParam, someData);
}
catch(Exception ex)
{
return new HttpExceptionResult(HttpStatusCode.InternalServerError, "Error uploading file");
}
}
}
希望这对遇到类似问题的人有所帮助
我们有一个休息界面,一切正常,但一些客户希望能够通过门户上传 xml 文件。
我解析上传的文件,然后创建相应的控制器,如果数据通过 rest 接口以正确的格式发送,就会使用该控制器。
一切正常,除了一条错误消息从嵌套控制器 return 发送到我的 ajax,仅当我 return Ok();我觉得这很奇怪。一定是在管道中很晚才出现问题,因为我似乎根本无法捕捉到任何异常。
我在下面用一些示例控制器评论了一些代码来说明我的意思。
public class FileController : ApiController
{
[HttpPost]
public async Task<IHttpActionResult> UploadFile()
{
// if I return Ok(); from here it works fine.. so it's not the ajax
// Get the file details
var someParam = blah;
var someData = blah;
try
{
var restController = new RestController();
return await restController.SomeMethod(someParam, someData);
}
catch(Exception ex)
{
// No error is ever caught here
return new HttpExceptionResult(HttpStatusCode.InternalServerError, "Error uploading file");
}
}
}
public class RestController : ApiController
{
[HttpPost]
public async Task<IHttpActionResult> SomeMethod(someParam, someData)
{
// This returns fine
return new HttpExceptionResult(HttpStatusCode.409, "Something already exists");
// this fails -> returns okay, but my ajax receives a 500 internal server error
return Ok();
}
}
public class HttpExceptionResult : IHttpActionResult
{
private readonly HttpStatusCode _statusCode;
private readonly string _message;
public HttpExceptionResult(HttpStatusCode statusCode, string message)
{
_statusCode = statusCode;
_message = message;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage(_statusCode);
response.Content = new StringContent(_message);
return Task.FromResult(response);
}
}
我确定有一些事情我可以立即尝试修复它(使用我自己的 class 到 return 200 代码),但我想了解为什么这是内部发生的。有人有什么想法吗?
再次重新审视这个问题,看看我是否可以解决它,到目前为止我只设法找到了一种方法。
技巧似乎是将当前的 ControllerContext 传递给新的 Controller。
public class FileController : ApiController
{
[HttpPost]
public async Task<IHttpActionResult> UploadFile()
{
var someParam = blah;
var someData = blah;
try
{
var restController = new RestController()
{
ControllerContext = this.ControllerContext
};
// This now works
return await restController.SomeMethod(someParam, someData);
}
catch(Exception ex)
{
return new HttpExceptionResult(HttpStatusCode.InternalServerError, "Error uploading file");
}
}
}
希望这对遇到类似问题的人有所帮助