在webApi2中,我可以通过继承IHttpActionResult来编写自定义ActionResult。
示例:
public class MenivaActionResult : IHttpActionResult
{
private readonly HttpRequestMessage _request;
private readonly ServiceResponseBase _response;
public MenivaActionResult(HttpRequestMessage request, ServiceResponseBase response)
{
_request = request;
_response = response;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken token)
{
HttpResponseMessage httpresponseMessage = _response.Exception != null
? _request.CreateErrorResponse((HttpStatusCode)_response.HttpCode,
_response.Exception.Message+":"+_response.Exception.HelpCode)
: _request.CreateResponse((HttpStatusCode)_response.HttpCode, _response.Data);
return Task.FromResult(httpresponseMessage);
}
}
ServiceResponseBase类对象包含来自服务层的所有异常和数据。
我如何将此代码移植到asp.net核心。我试过,但我不知道如何从.net核心中的 HttpRequestMessage 对象创建响应消息。 IActionResult 只有Task ExecuteResultAsync(ActionContext context)
方法。如何修改此方法的响应
答案 0 :(得分:23)
以下是一个例子:
public class TestResult
{
public Exception Exception { get; set; }
public object Data { get; set; }
}
public class TestActionResult : IActionResult
{
private readonly TestResult _result;
public TestActionResult(TestResult result)
{
_result = result;
}
public async Task ExecuteResultAsync(ActionContext context)
{
var objectResult = new ObjectResult(_result.Exception ?? _result.Data)
{
StatusCode = _result.Exception != null
? StatusCodes.Status500InternalServerError
: StatusCodes.Status200OK
};
await objectResult.ExecuteResultAsync(context);
}
}
如果您从某个操作中返回非ObjectResult
,则 IActionResult
是您转换结果的类型。它会为你做内容协商。
您也可以从ObjectResult
继承并设置要在构造函数中写入的状态代码和数据。
有关ASP.NET Core中内容协商的更多信息:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/formatting#content-negotiation
答案 1 :(得分:2)
尽管@juunas的答案在技术上是正确的,但您真正想要实现的是自定义错误处理。更好的方法是使用动作过滤器,中间件过滤器或单独的中间件来解耦这个逻辑(取决于你要覆盖的范围)。
主要思想是控制器不应负责处理异常。它应该以OK状态返回预期结果或者说错误(抛出异常)并委托管道的其他部分如何处理问题。
查看SO:Error handling in ASP.NET Core 1.0 Web API (Sending ex.Message to the client)作为示例。 Error Handling in ASP.NET Core doc也可能有用。
答案 2 :(得分:0)
为什么不直接使用 StatusCode 方法?像这样的例子:
public async Task<IActionResult> ExamleEndpoint()
{
// ... some code here which concatenates result string and selects a status code
var statusCode = HttpStatusCode.OK;
var message = "Some string response here but StatusCode also accepts Object value";
return StatusCode((int) statusCode, message);
}