如何在asp.net核心中编写自定义actionResult

时间:2017-03-04 09:28:29

标签: c# asp.net asp.net-core .net-core

在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)方法。如何修改此方法的响应

3 个答案:

答案 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);
}